BeansAI
ModelsPricingDocs
Sign inSign up
ModelsPricingDocs
Sign inSign up

Quickstart

  • Overview

Clients

  • Claude Code
  • CC Switch
  • OpenClaw
  • Roo Code
  • OpenCode
  • Codex CLI
  • GPT Image 2
  • Seedance 2.0
  • SkyReels V4
  • Mureka Song
  • Cursor
  • Cherry Studio

Reference

  • Raw API
← Back to Docs

GPT Image 2

Generate and edit images with gpt-image-2 through the OpenAI-compatible BeansAI API.

Overview

Use the same BeansAI key and base URL as chat models. Text-to-image goes to POST /images/generations; reference-image edits go to POST /images/edits.

Most image upstream nodes support streaming. Add stream: true to production image calls so proxies receive progress events instead of waiting for one large response.

Text to image

curl
curl https://api.beansai.dev/v1/images/generations \
  -N \
  -H "Authorization: Bearer sk-beans-..." \
  -H "Accept: text/event-stream" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "A clean product photo of a green coffee bean mascot on a white background",
    "size": "1024x1024",
    "quality": "high",
    "n": 1,
    "response_format": "b64_json",
    "stream": true
  }'

Reference image edit

Send reference images as data URLs in images[].image_url. PNG, JPEG, and WebP inputs are the safest choices.

shell
IMAGE_B64="$(base64 -i reference.png | tr -d '\n')"

curl https://api.beansai.dev/v1/images/edits \
  -N \
  -H "Authorization: Bearer sk-beans-..." \
  -H "Accept: text/event-stream" \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"gpt-image-2\",
    \"prompt\": \"Keep the same product, place it on a polished studio desk\",
    \"images\": [{ \"image_url\": \"data:image/png;base64,$IMAGE_B64\" }],
    \"size\": \"1024x1024\",
    \"quality\": \"high\",
    \"response_format\": \"b64_json\",
    \"stream\": true
  }"

Streaming

curl
curl https://api.beansai.dev/v1/images/generations \
  -N \
  -H "Authorization: Bearer sk-beans-..." \
  -H "Accept: text/event-stream" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "A cinematic poster for an AI API gateway called BeansAI",
    "size": "2016x1344",
    "quality": "high",
    "response_format": "b64_json",
    "stream": true
  }'

Streamed responses are SSE. Read *.partial_image for previews when available, then read *.completed and decode the b64_json image payload.

Pricing tiers

BeansAI charges gpt-image-2 by preset size and quality tier, not by a single flat image price. The request is normalized to one of the supported preset sizes below; unsupported custom sizes are rejected.

Preset sizelowmediumhigh
1024x1024$0.0059$0.0527$0.2107
1024x768$0.0040$0.0361$0.1445
1008x672$0.0035$0.0309$0.1234
1088x608$0.0029$0.0259$0.1035
1440x480$0.0016$0.0155$0.0620
768x1024$0.0040$0.0361$0.1445
672x1008$0.0035$0.0309$0.1234
608x1088$0.0029$0.0259$0.1035
480x1440$0.0016$0.0155$0.0620
2048x2048$0.0119$0.1070$0.4282
2048x1536$0.0074$0.0667$0.2668
2016x1344$0.0062$0.0543$0.2170
2048x1152$0.0047$0.0424$0.1695
2784x928$0.0028$0.0264$0.1056
1536x2048$0.0074$0.0667$0.2668
1344x2016$0.0062$0.0543$0.2170
1152x2048$0.0047$0.0424$0.1695
928x2784$0.0028$0.0264$0.1056
2880x2880$0.0198$0.1779$0.7116
2880x2160$0.0119$0.1066$0.4262
3456x2304$0.0132$0.1148$0.4591
3840x2160$0.0111$0.1001$0.4003
3840x1280$0.0042$0.0398$0.1593
2160x2880$0.0119$0.1066$0.4262
2304x3456$0.0132$0.1148$0.4591
2160x3840$0.0111$0.1001$0.4003
1280x3840$0.0042$0.0398$0.1593

Python

image.py
import base64
import json
import requests

res = requests.post(
    "https://api.beansai.dev/v1/images/generations",
    headers={
        "Authorization": "Bearer sk-beans-...",
        "Accept": "text/event-stream",
    },
    json={
        "model": "gpt-image-2",
        "prompt": "A minimal green coffee bean logo on a white background",
        "size": "1024x1024",
        "quality": "high",
        "response_format": "b64_json",
        "stream": True,
    },
    stream=True,
    timeout=600,
)
res.raise_for_status()

image_b64 = None
for line in res.iter_lines(decode_unicode=True):
    if not line or not line.startswith("data:"):
        continue
    payload = line[5:].strip()
    if payload == "[DONE]":
        break
    event = json.loads(payload)
    if str(event.get("type", "")).endswith(".completed"):
        image_b64 = event.get("b64_json")
        break

if not image_b64:
    raise RuntimeError("No completed image event returned")

with open("beansai-image.png", "wb") as f:
    f.write(base64.b64decode(image_b64))

JavaScript

image.mjs
import fs from "node:fs";

const res = await fetch("https://api.beansai.dev/v1/images/generations", {
  method: "POST",
  headers: {
    Authorization: "Bearer sk-beans-...",
    Accept: "text/event-stream",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "gpt-image-2",
    prompt: "A friendly AI dashboard illustration with green accents",
    size: "1024x1024",
    quality: "high",
    response_format: "b64_json",
    stream: true,
  }),
});

if (!res.ok) throw new Error(await res.text());
if (!res.body) throw new Error("No response body");

const decoder = new TextDecoder();
const reader = res.body.getReader();
let buffer = "";
let image = "";

function processBlock(block) {
  const data = block
    .split(/\r?\n/)
    .filter((line) => line.startsWith("data:"))
    .map((line) => line.slice(5).trimStart())
    .join("\n")
    .trim();
  if (!data || data === "[DONE]") return;
  const event = JSON.parse(data);
  if (String(event.type || "").endsWith(".completed")) {
    image = event.b64_json || "";
  }
}

while (!image) {
  const { done, value } = await reader.read();
  if (done) break;
  buffer += decoder.decode(value, { stream: true });
  const blocks = buffer.split(/\r?\n\r?\n/);
  buffer = blocks.pop() || "";
  for (const block of blocks) processBlock(block);
}

if (!image && buffer.trim()) processBlock(buffer);
if (!image) throw new Error("No completed image event returned");
fs.writeFileSync("beansai-image.png", Buffer.from(image, "base64"));

Tips

  • Use response_format: "b64_json" when you want to save the image yourself.
  • Common sizes are 1024x1024, 2048x1152, and 3840x2160. Use the dashboard Playground when you want to test a prompt visually first.
  • Add stream: true by default for image integrations. It reduces idle proxy timeouts and still returns the final image in a completed SSE event.