camelAI Documentation

Guides

Image generation API and agent images on camelRun

Generate and edit images with POST /v1/images, or let an agent make them with the generate_image built-in. Billed per token at OpenAI prices.

View as Markdown · Docs index for coding agents

POST /v1/images makes images from a prompt, or edits images you give it, with no agent. An agent makes them with the generate_image built-in.

Images are made with OpenAI's gpt-image-2.5-flare, on the OpenAI key a model call of yours would use: a key scope's, your own (PUT /v1/providers/openai/key), else the platform's. On the platform's key, a prepaid account pays per token at OpenAI's prices (see Billing).

Make an image

const { images: [image], costUsd } = await agents.images.generate("A watercolor camel crossing dunes at dawn", { size: "1536x1024" });
await writeFile("camel.png", Buffer.from(image.data!, "base64"));
json
{
  "images": [{ "contentType": "image/png", "width": 1536, "height": 1024, "data": "iVBORw0KGgo…" }],
  "model": "openai/gpt-image-2.5-flare", "usage": { "inputTokens": 16, "outputTokens": 343 }, "costUsd": 0.01037
}
Field
promptWhat to make, or how to change the images given (at most 32,000 characters)
size1024x1024 (default), 1536x1024 (landscape) or 1024x1536 (portrait)
qualitylow, medium (default) or high
formatpng (default), jpeg or webp
backgroundtransparent (with png or webp) or opaque; the model chooses when left out
nHow many images, 1 to 4 (default 1)
keyScopeA key scope whose OpenAI key goes first
volumeId, pathSave the images in a volume of yours instead (see Save to a volume)
subject, context, actorWho it is for and who asked, carried to its usage.recorded event, as an agent's identity is
bucketWith end-user credits on: which of the subject's buckets pays

The answer comes when the images are ready: about 10 seconds for one at low or medium, longer at high (OpenAI allows up to two minutes for a complex prompt). The images come back as base64 and nothing is kept.

  • A retry makes (and bills) new images. Requests take no Idempotency-Key.
  • API tokens and OAuth tokens may make images; browser tokens may not.
  • Runs-per-minute limits count each request as a run.

Edit images

Give up to 4 images (PNG, JPEG or WebP) in images, and the prompt says how to change or combine them:

const { images } = await agents.images.edit("Put this camel on a beach", [await readFile("camel.png")], { quality: "high" });
  • In JSON, each image is {"data": "<base64>"} or {"url": "https://…"}, which camelRun fetches from the public internet (three redirects at most).
  • As multipart, each image is a file part named image, and the other fields are form fields (context as JSON).
  • A mask (a part, or {data} / {url}) says where the first image may change: transparent there. It is an image with an alpha channel, in the first image's format and size.

Save to a volume

With volumeId (one of your volumes), the images are saved there, under path (a directory, /images by default), and the answer gives their paths instead of their bytes:

json
{ "images": [{ "contentType": "image/png", "width": 1024, "height": 1024, "volumeId": "vol_…", "path": "/images/image-20261009T104512-3fa9c1.png", "size": 1316554, "version": 1 }], … }

Read them with GET /v1/volumes/{id}/files/{path}, or hand a browser a signed link to one (POST /v1/volumes/{id}/links). They count toward your storage like any file.

In an agent

Give an agent (or its definition, or a stateless run) the generate_image built-in:

const agent = await agents.upsert("illustrator", { builtins: ["generate_image"] });
const run = await agent.run("Draw a camel crossing dunes at dawn, as a watercolor, and show it to me");

The model calls generate_image with a prompt, and optionally images (paths of images in its files, such as an attachment or one it made before, to edit or combine), size, quality (medium by default), format and background.

  • Each call makes one image, saved to the agent's workspace under tool-outputs/generate_image/<call>/, and answers with its path, size and cost.
  • The model is shown the image, so it can check it or describe it. It presents it to the user with present_file, which emits a file_presented event with a signed link.
  • A stateless run with generate_image gets a workspace for its images.

Each image is billed as a request to POST /v1/images is, with the run's facts on its usage.recorded event (agentId, requestId, actor, the agent's identity and key scope). It counts against the agent's spend limit and the run's own spendLimit: a call whose estimate is more than what is left fails before anything is sent, and the model is told why. The run's usage.imageCostUsd says what its images cost.

Saving a definition or an agent with generate_image when the account has no OpenAI key to use answers with a warning, and a call then fails with how to add one.

Safety and errors

OpenAI's safety system checks the prompt, the images given and the image made. A request it refuses is a 400 IMAGE_REFUSED, which names the stage (input: the prompt or images given; output: the image made) and the categories it gives, never the prompt:

json
{ "type": "error", "error": "OpenAI's safety system refused this request (violence)", "code": "IMAGE_REFUSED", "stage": "input", "categories": ["violence"] }

A refused request is not charged. In an agent, the model is told it was refused and why.

Error
400A request OpenAI cannot take, with its reason
400 IMAGE_UNAVAILABLENo OpenAI key to use
413 IMAGE_TOO_LARGEAn image to edit is too large
415 UNSUPPORTED_IMAGEAn image to edit is not PNG, JPEG or WebP
502 IMAGE_FAILEDThe provider failed

Limits

Prompt32,000 characters
Images to edit4, PNG, JPEG or WebP, 25 MB each, 50 MB in all, at most 8,000 pixels a side
Images made4 per request
Time3 minutes for the provider to answer

Billing

On the platform's key, images cost what OpenAI charges for gpt-image-2.5-flare, with no camelRun markup: $5 per million text tokens in, $8 per million image tokens in (images given to edit) and $30 per million image tokens out. The tokens are those OpenAI reports for the request. One image costs:

Quality1024x10241536x1024 or 1024x1536
low$0.0059 (196 tokens)$0.0047 (158 tokens)
medium$0.0132 (439 tokens)$0.0103 (343 tokens)
high$0.0527 (1,756 tokens)$0.0412 (1,372 tokens)

Add the prompt (a few hundredths of a cent), and about $0.008 to $0.012 for each image given to edit (1,024 tokens for a square one, 1,536 for a wide one). A spend limit refuses a request whose estimate (the most it can cost) is more than what is left of it, before anything is sent. On your own key or a key scope's, OpenAI bills you and camelRun charges nothing.

Either way it is recorded:

  • In GET /v1/usage, a row per day with kind: "image" and model openai/gpt-image-2.5-flare (responses counts images).
  • In the hour's ledger entry, as image (micro-USD) and images.
  • As a usage.recorded event with kind: "image", images, and its tokens (input: text and images in, output: images out). Made with no agent, it has agentId: null and the subject, context and actor you sent. The older usage webhook (/v1/usage-webhook) carries model responses only.

Images count toward your monthly cap and prepaid credit, as a model response does. See Pricing.

Privacy

Prompts and images are never written to camelRun's logs, which carry sizes, quality, tokens and timings. A request without volumeId keeps nothing; with one, the images are kept in your volume until you delete them. OpenAI processes the prompt and images under its API data policy (not used for training).