Skip to content
JamFrame
Docs menu

AI text, images and translation

Let AI write a layer's text, make its image or translate every text layer while a template renders. The keys, options, limits, costs and errors.

A text or image layer can be filled by AI when the template renders. You send a prompt, and JamFrame writes the text or makes the picture, then renders the file. You can also translate all the text of a render into another language. This page covers the API side. To set up AI layers in the editor, see AI layers.

Before you start

AI works on layers that have a key (a dynamic field), such as headline or photo. A layer can get its prompt in two ways:

  • In the editor, in the layer’s AI section. Then a normal render fills it, and you don’t need to send anything extra.
  • In the request, with a .prompt key. This works on any text or image layer with a key, even one with no AI set up.

The layer’s own text or image is its saved fallback. It shows wherever AI doesn’t run.

Send a prompt with a render

This request writes the headline with AI, makes the photo with AI, and translates the result into Spanish:

curl https://api.jamframe.com/v1/render \
  -H "Authorization: Bearer $JAMFRAME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "templateId": "YOUR_TEMPLATE_ID",
    "modifications": {
      "product": "Cold brew",
      "headline.prompt": "Write a 6-word headline about {{product}}",
      "headline.tone": "playful",
      "photo.prompt": "A glass of {{product}} on a marble table, morning light",
      "photo.style": "photo"
    },
    "translate": true,
    "lang": "es",
    "ai": { "onError": "fallback" }
  }'
const res = await fetch("https://api.jamframe.com/v1/render", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.JAMFRAME_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    templateId: "YOUR_TEMPLATE_ID",
    modifications: {
      product: "Cold brew",
      "headline.prompt": "Write a 6-word headline about {{product}}",
      "headline.tone": "playful",
      "photo.prompt": "A glass of {{product}} on a marble table, morning light",
      "photo.style": "photo",
    },
    translate: true,
    lang: "es",
    ai: { onError: "fallback" },
  }),
});
const { data, warnings } = await res.json();
console.log(data.content, data.aiCredits, warnings);
import os
import requests

res = requests.post(
    "https://api.jamframe.com/v1/render",
    headers={"Authorization": f"Bearer {os.environ['JAMFRAME_API_KEY']}"},
    json={
        "templateId": "YOUR_TEMPLATE_ID",
        "modifications": {
            "product": "Cold brew",
            "headline.prompt": "Write a 6-word headline about {{product}}",
            "headline.tone": "playful",
            "photo.prompt": "A glass of {{product}} on a marble table, morning light",
            "photo.style": "photo",
        },
        "translate": True,
        "lang": "es",
        "ai": {"onError": "fallback"},
    },
)
body = res.json()
print(body["data"]["content"], body["data"].get("aiCredits"))

The answer is a normal render answer, plus aiCredits: the AI credits this render used.

{
  "data": {
    "content": "https://cdn.jamframe.com/renders/…/1d2e3f4a.png?Expires=…",
    "expiresAt": "2026-11-14T12:05:00.000Z",
    "type": "url",
    "format": "png",
    "pages": [1],
    "credits": 1,
    "renderId": "clx8n0q1r0009abcd1234efgh",
    "responseTime": 6240,
    "aiCredits": 6
  }
}

For every other render option, see Render images and PDFs.

AI keys

Add these keys to modifications. Replace headline and photo with your own layer keys.

Key Layers What it does
headline.prompt Text and image What to write or draw. Up to 2,000 characters. "" turns the layer’s AI off, so it shows its saved fallback.
headline.tone Text The tone of voice, such as friendly or formal. Up to 60 characters.
headline.maxWords Text At most this many words, from 1 to 300. Longer answers are cut.
photo.style Image The look, such as photo or flat illustration. Up to 120 characters.
photo.reference Image The http or https link of an image to edit, instead of making a new one.
headline Text and image A plain value skips the AI. The layer shows your value as it is.

.tone, .maxWords, .style and .reference only work on a layer that has a prompt, from the editor or from .prompt.

To change one page only, put the page first, like any key: [email protected]. See Modifications.

Values in prompts

A prompt can use {{name}} variables. JamFrame fills them before it calls the AI:

  1. From the values you send, such as "product": "Cold brew", or else the template’s own value for that variable.
  2. If there is none, from the text of a text layer whose key is name.
  3. If neither has a value, the variable becomes empty and the answer has a warning.

You can send a value that only a prompt uses, such as product above. It is not reported as an unknown key. Once its variables are filled, a prompt can be at most 3,000 characters.

AI images

The picture is made to fit the layer’s box. JamFrame picks the closest of these shapes: 1:1, 4:5, 5:4, 3:4, 4:3, 2:3, 3:2, 9:16, 16:9 or 21:9. The picture fills the box and is cropped at the edges if needed. With Smart Resize, every size uses the same picture.

Translate a render

Send "translate": true with lang, a language tag such as es, fr, pt-BR or zh-Hant. You need both: one without the other is a 400 VALIDATION_ERROR.

JamFrame translates the final text of every visible text layer, after your values and the AI text are in. These stay as they are: variables without a value, links, email addresses, @handles, #hashtags and numbers such as times, dates and prices.

If a translation drops or changes one of those, JamFrame keeps that text in the original language, adds a warning, and doesn’t charge for it.

When the AI fails

ai.onError says what happens when an AI call fails:

Value What happens
fail (default) The render fails with the AI’s error code. Nothing is charged.
fallback The render goes on. AI layers show their saved fallback, and nothing is translated. Results JamFrame already has from earlier renders are still used. The answer has a warning, and no AI credits are charged.

Use fallback when a file with the saved text is better than no file at all.

Limits per render

These count every page and every size of one render together:

Limit Value
Different text prompts 50
Different AI images 10
Text to translate 50,000 characters
Prompt length 2,000 characters as written, 3,000 once variables are filled

Over a limit, the render is refused with 400 VALIDATION_ERROR before anything runs, and nothing is charged.

Where AI runs

Render AI runs?
POST /v1/render, with or without "async": true Yes
Test renders in the app Yes
Workflow runs Yes
Signed URLs, dynamic URLs and forms Never

Signed URLs, dynamic URLs and forms are public, so they never spend your AI credits. AI layers there show their saved fallback, and AI keys such as headline.prompt come back as unknown keys in warnings.

Cost and caching

AI uses AI credits, which are separate from render credits. The render itself still costs its normal render credits. For what each kind of AI work costs, see What AI features cost. The words of all the text prompts in one render are counted together.

So the example above costs 1 (headline) + 4 (photo) + 1 (translation) = 6 AI credits, plus 1 render credit.

  • AI credits are charged once per render, and only when the render succeeds. A failed render costs nothing.
  • Every page and every size of one render share the same AI results.
  • JamFrame keeps each result for 30 days in your workspace. The same prompt with the same settings gives the same result, for free. aiCredits is then 0.
  • To get a new result, change the prompt. For an edited image, change the reference link.

aiCredits is in the answer only for renders with AI layers or translate. For how many AI credits your plan has, see Credits.

Errors

A render with AI can fail with one of these codes. Nothing is charged. With "ai": { "onError": "fallback" }, each of them renders the saved fallback instead, except a 400 for a passed limit or a bad key value.

Status error What to do
400 VALIDATION_ERROR A limit was passed, a key has a bad value, or the reference image couldn’t be downloaded. Read message.
402 AI_CREDITS_EXCEEDED Your AI credits for this period are used up. detail shows what’s left and when the period ends.
422 AI_CONTENT_REFUSED The AI provider refused the prompt or the result under its content policy. Change the prompt.
422 AI_BAD_REQUEST The AI provider couldn’t use this input, such as an image it can’t read.
429 AI_RATE_LIMITED The AI provider is busy. Wait a moment and try again.
502 AI_BAD_OUTPUT The AI didn’t give a usable result. Try again.
502 AI_UPSTREAM_ERROR The AI provider failed. Try again.
503 AI_UNAVAILABLE AI is off right now. Try later, or use fallback.
504 AI_TIMEOUT The AI didn’t answer in time. Try again.

See Errors for every other code.

Last updated

Still stuck?

Email [email protected] and a real person will reply. Tell us the template you were using and what you expected to happen.