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/createAuthentication: 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.
Request
Section titled “Request”Minimum required
Section titled “Minimum required”You address elements by the layer name you gave them in the editor’s Layers panel, and change them through modifications:
| Field | Type | Description |
|---|---|---|
template_id | string | The 12-character ID of your image template (copy from the images dashboard). |
modifications | array | Elements 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#.
All parameters
Section titled “All parameters”| Field | Type | Required | Default | Description |
|---|---|---|---|---|
template_id | string | ✅ | — | 12-character template short ID. |
modifications | array | — | — | Elements to change, addressed by layer name. See Modifications. Up to 100 items. |
format | string | — | "png" | Output format: "png" (lossless, supports transparency), "jpeg" (smaller, no transparency), or "webp" (modern compression). |
width | integer | — | template width | Output width in pixels; height follows the template’s aspect ratio. Min 100, max 4000. Defaults to the template’s native canvas width. |
quality | integer | — | 85 | Compression quality for jpeg and webp (1–100). Ignored for png. |
export_type | string | — | "url" | "url" uploads the image to our CDN and returns a signed URL. "binary" returns the raw image bytes. |
expiration | integer | — | 86400 | URL expiration in seconds. Min: 60, max: 604800 (7 days). Only applies when export_type="url". |
filename | string | — | "document" | Custom filename (without extension). Alphanumeric, _, -, . only. Max 100 chars. |
store_s3 | boolean | — | false | Upload to your configured S3 bucket instead of our CDN. Requires an S3 integration. |
s3_filepath | string | — | — | Path prefix inside your S3 bucket. Overrides default_prefix. Max 500 chars. |
s3_bucket | string | — | — | Override the bucket name from your S3 integration (3–63 chars, lowercase). |
version | string | — | — | Template version tag (e.g. "prod") or numeric version (e.g. "3"). Omit to use the current draft. Max 50 chars. |
Sizing
Section titled “Sizing”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.
Modifications
Section titled “Modifications”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:
| Property | Type | Description |
|---|---|---|
name | string | Layer name to modify (required). |
text | string | Replace the layer’s text. Rendered as literal text — HTML and {{ }} are not interpreted. |
image_url | string | Set 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. |
color | string | Text color (any CSS color). |
background | string | Background color (any CSS color). |
hidden | boolean | Hide (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
namematches no layer, the render still succeeds and the skipped name is listed in the responsewarnings. - Duplicate names apply to all. If several layers share a name, the modification is applied to every one of them.
Response
Section titled “Response”export_type = "url" (default)
Section titled “export_type = "url" (default)”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}| Field | Type | Description |
|---|---|---|
url | string | Signed URL to download the image (expires after expires_in seconds). |
filename | string | Final filename of the generated image. |
credits_remaining | number | Credits left in your team’s balance after this call. |
expires_in | number | Seconds until the signed URL expires. |
warnings | array | Present only when a modification’s layer name matched no element. Lists the skipped names. |
export_type = "binary"
Section titled “export_type = "binary"”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/pngContent-Disposition: attachment; filename="HMQywVpZxqAM.png"X-Credits-Remaining: 99store_s3 = true
Section titled “store_s3 = true”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}Formats and sizing
Section titled “Formats and sizing”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
}' Binary response
Section titled “Binary response”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"
}' Errors
Section titled “Errors”| Status | Error | When |
|---|---|---|
| 400 | BAD_REQUEST | The template is not an image template (use create-pdf), or has more than one page. |
| 401 | UNAUTHORIZED | Missing or invalid API key. |
| 402 | INSUFFICIENT_CREDITS | Your team’s credit balance is 0. |
| 403 | FORBIDDEN | The template does not belong to your team. |
| 404 | TEMPLATE_NOT_FOUND | template_id does not exist. |
| 429 | RATE_LIMIT_EXCEEDED | Rate limit hit (see response headers). |
| 500 | INTERNAL_ERROR | Rendering failed. Credit is automatically refunded. |
See the full list in the API Reference overview.