Gpt Image 2 logo

Gpt Image 2

Community
robonuggets
gpt-image-2

Generate or edit images with OpenAI's GPT Image 2 (ChatGPT Images 2.0) via Fal AI. Two endpoints — text-to-image AND image edit (reference images + optional mask). Best-in-class for fine typography — chalkboards, signs, menus, posters, packaging, UI mockups, anything with legible text. Sync API, 1-4 images per call, custom dimensions up to 8.3MP. Includes pointer to a 700+ community prompt library (CC BY 4.0) for style/category inspiration. Triggers on gpt image 2, gpt-image-2, chatgpt image, openai image, typography image, sign mockup, poster mockup, menu image, packaging mockup, edit image, image edit, modify image, gpt image 2 prompt, awesome gpt-image-2.

Overview

Publisherrobonuggets
Repositorygpt-image-2-skill
Skill namegpt-image-2
Stars
74
Forks
14
Bundled files
Instructions only
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by robonuggets on GitHub. Read the source before you install it.

Installation

Install the Gpt Image 2 AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/robonuggets/gpt-image-2-skill/tree/main
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/robonuggets/gpt-image-2-skill.git \
  .claude/skills/gpt-image-2
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Gpt Image 2 in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Gpt Image 2 on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Gpt Image 2 is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

GPT Image 2 (ChatGPT Images 2.0)

OpenAI's latest image model — the strongest model available for legible text inside images. Use this when the picture is the typography: chalkboards, store signs, hand-lettered posters, menu boards, magazine covers, packaging mockups, UI screenshots, book covers.

Two endpoints:

  • Text-to-image (openai/gpt-image-2) — generate from a prompt
  • Image edit (openai/gpt-image-2/edit) — modify a reference image (with optional mask for region-specific edits)
FieldValue
Model IDopenai/gpt-image-2 (text-to-image) · openai/gpt-image-2/edit (edit)
ProviderFal AI
MethodSync (POST → response with image URLs, no polling)
TypeImage generation + editing
API Key.env → FAL_KEY
Docshttps://fal.ai/models/openai/gpt-image-2 · https://fal.ai/models/openai/gpt-image-2/edit

Setup

  1. Get a Fal API key from https://fal.ai/dashboard/keys
  2. Add to your .env file (or wherever your project keeps secrets):
    FAL_KEY=your_key_here
  3. That's it. Sync API — no SDK install required, just curl or fetch.

How to call it

Auth header is Authorization: Key {key} — not Bearer. This applies to both endpoints.

Text-to-image — minimum request

bash
curl -s -X POST "https://fal.run/openai/gpt-image-2" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "A vintage diner chalkboard reading TODAY SPECIAL — Lobster Roll $24"}'

Text-to-image — full request

json
{
  "prompt": "...",
  "image_size": "landscape_4_3",
  "quality": "medium",
  "num_images": 1,
  "output_format": "png"
}

Image edit — minimum request

Pass one or more public image URLs as references. Prompt describes the edit.

bash
curl -s -X POST "https://fal.run/openai/gpt-image-2/edit" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Same workers, same beam — but they are all on phones now. One taking a selfie, one annoyed on a call. Hard hats with AirPods.",
    "image_urls": ["https://v3b.fal.media/files/b/.../reference.png"]
  }'

Image edit — full request

json
{
  "prompt": "...",
  "image_urls": ["https://...", "https://..."],
  "image_size": "auto",
  "quality": "medium",
  "num_images": 1,
  "output_format": "png",
  "mask_url": "https://.../mask.png"
}
  • image_size: "auto" infers dimensions from the reference image — usually what you want.
  • mask_url (optional) is a black/white image marking the region to edit. White = edit, black = keep. Use for surgical edits ("only change the sky").

Response (both endpoints)

json
{
  "images": [
    {
      "url": "https://v3b.fal.media/files/b/.../result.png",
      "content_type": "image/png",
      "file_name": "result.png"
    }
  ]
}

Download images[i].url immediately — Fal URLs may expire.

Where do image_urls come from?

The reference image needs to be at a publicly accessible URL. Options:

  1. Fal's own storage — use the JS/Python client's upload helper (fal.storage.upload(file) in JS, fal_client.upload_file(path) in Python).
  2. Reuse a previous Fal output URL — outputs from any Fal model can be passed straight back as image_urls to chain edits.
  3. Any public host — S3, GitHub raw, your own server, etc. Must be a direct image URL (not an HTML page).

If your project uses Kie AI, their file upload endpoint at https://kieai.redpandaai.co/api/file-stream-upload works fine and returns a URL you can pass to Fal — see the bash recipe below for an example.


Parameters

Text-to-image (openai/gpt-image-2)

ParamRequiredOptionsDefault
promptYesstring—
image_sizeNopreset name OR {width, height}"landscape_4_3"
qualityNo"low", "medium", "high""medium" (Jay's default — high is overkill for most cases, ~3.5x more expensive)
num_imagesNo1 – 41
output_formatNo"jpeg", "png", "webp""png"
sync_modeNobool — return base64 data URI inlinefalse

Image edit (openai/gpt-image-2/edit)

ParamRequiredOptionsDefault
promptYesstring — describe the edit—
image_urlsYesarray of public image URLs—
image_sizeNopreset, {width, height}, or "auto""auto" (infer from input)
qualityNo"low", "medium", "high""medium"
num_imagesNo1 – 41
output_formatNo"jpeg", "png", "webp""png"
sync_modeNobool — return base64 data URI inlinefalse
mask_urlNoURL of B/W mask (white = edit, black = keep)—

Image sizes

Preset names: square_hd, square, portrait_4_3, portrait_16_9, landscape_4_3, landscape_16_9.

Custom dimensions — pass an object:

json
"image_size": { "width": 1536, "height": 1024 }

Constraints on custom sizes:

  • Both dimensions must be multiples of 16
  • Max edge: 3840px
  • Aspect ratio: ≤ 3:1
  • Total pixels between 655,360 and 8,294,400 (~640×1024 min, ~3840×2160 max)

Pricing

Token-based, billed via Fal:

Token typeInputCachedOutput
Text$5 / 1M$1.25 / 1M$10 / 1M
Image$8 / 1M$2 / 1M$30 / 1M

Per-image rough cost (landscape_4_3 = 1536×1024):

  • low ≈ $0.02 per image
  • medium ≈ $0.05 per image ← default
  • high ≈ $0.18 per image

quality is the biggest cost lever. Default to medium — that's the sweet spot for most work. Bump to high only when typography/detail really matters and the image is a final. low for cheap drafts. Check actual usage in the Fal dashboard.


When to use vs other models

ScenarioEndpointNotes
Sign / chalkboard / poster with texttext-to-imageBest in class for typography
Magazine cover / book covertext-to-image
Menu board / packaging mockuptext-to-image
UI screenshot mockuptext-to-image
Modify an existing image ("change the sky", "swap the logo", "add text")editPass image as image_urls, describe the change
Surgical region edit ("only change this corner")edit + mask_urlMask defines the editable region
Iterative refinementeditFeed previous output URL back in
Photoreal portraitotherUse Nano Banana / Flux
Style transfer with strong style preservationotherGPT Image 2 edit reinterprets more than it preserves
Need < $0.02 per renderotherSwitch model — even low quality here is comparable to other models' default

Recipe — Node.js

One helper, both endpoints. Drop in a .js file and run with node. Forward slashes in paths work fine on Windows.

javascript
import fs from 'node:fs';
import path from 'node:path';

const FAL_KEY = process.env.FAL_KEY ||
  fs.readFileSync('.env', 'utf8').match(/FAL_KEY=(.+)/)[1].trim();

// Pass image_urls to use the edit endpoint; omit for text-to-image.
async function gptImage2({
  prompt,
  image_urls,
  mask_url,
  image_size,
  quality = 'medium',
  num_images = 1,
  output_format = 'png',
  outDir = './output',
  label = 'gpt2',
}) {
  fs.mkdirSync(outDir, { recursive: true });

  const isEdit = Array.isArray(image_urls) && image_urls.length > 0;
  const url = isEdit
    ? 'https://fal.run/openai/gpt-image-2/edit'
    : 'https://fal.run/openai/gpt-image-2';

  const body = { prompt, quality, num_images, output_format };
  if (isEdit) {
    body.image_urls = image_urls;
    body.image_size = image_size ?? 'auto';
    if (mask_url) body.mask_url = mask_url;
  } else {
    body.image_size = image_size ?? 'landscape_4_3';
  }

  const res = await fetch(url, {
    method: 'POST',
    headers: { 'Authorization': `Key ${FAL_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });

  const json = await res.json();
  if (!json.images?.length) throw new Error(`No images returned: ${JSON.stringify(json)}`);

  const ts = Date.now();
  const saved = [];
  for (let i = 0; i < json.images.length; i++) {
    const suffix = json.images.length > 1 ? `_${i + 1}` : '';
    const fname = `${label}_${ts}${suffix}.${output_format}`;
    const fp = path.join(outDir, fname);
    const buf = Buffer.from(await (await fetch(json.images[i].url)).arrayBuffer());
    fs.writeFileSync(fp, buf);
    saved.push(fp);
    console.log(`Saved: ${fp}`);
  }
  return saved;
}

// Text-to-image
await gptImage2({
  prompt: 'A chalkboard sign on a brick wall, hand-lettered: "OPEN AT 7"',
  label: 'chalkboard',
});

// Edit an existing image
await gptImage2({
  prompt: 'Same scene but everyone is on their phone now. One taking a selfie, one on a call.',
  image_urls: ['https://v3b.fal.media/files/b/.../original.png'],
  label: 'phones_edit',
});

Recipe — Python

One helper, both endpoints. Pass image_urls for the edit variant; omit for text-to-image.

python
import os, time, requests, pathlib

FAL_KEY = os.environ['FAL_KEY']

def gpt_image_2(prompt, image_urls=None, mask_url=None, image_size=None,
                quality='medium', num_images=1, output_format='png',
                out_dir='./output', label='gpt2'):
    pathlib.Path(out_dir).mkdir(parents=True, exist_ok=True)
    is_edit = bool(image_urls)
    url = 'https://fal.run/openai/gpt-image-2/edit' if is_edit else 'https://fal.run/openai/gpt-image-2'

    body = {'prompt': prompt, 'quality': quality,
            'num_images': num_images, 'output_format': output_format}
    if is_edit:
        body['image_urls'] = image_urls
        body['image_size'] = image_size or 'auto'
        if mask_url:
            body['mask_url'] = mask_url
    else:
        body['image_size'] = image_size or 'landscape_4_3'

    res = requests.post(url,
        headers={'Authorization': f'Key {FAL_KEY}', 'Content-Type': 'application/json'},
        json=body)
    data = res.json()
    if not data.get('images'):
        raise RuntimeError(f'No images: {data}')

    ts = int(time.time() * 1000)
    saved = []
    for i, img in enumerate(data['images']):
        suffix = f'_{i+1}' if len(data['images']) > 1 else ''
        fp = f'{out_dir}/{label}_{ts}{suffix}.{output_format}'
        with open(fp, 'wb') as f:
            f.write(requests.get(img['url']).content)
        saved.append(fp)
        print(f'Saved: {fp}')
    return saved

# Text-to-image
gpt_image_2(prompt='A chalkboard reading "OPEN AT 7"', label='chalkboard')

# Edit
gpt_image_2(
    prompt='Same scene but everyone is on their phone now',
    image_urls=['https://v3b.fal.media/files/b/.../original.png'],
    label='phones_edit',
)

Recipe — bash (one-shot)

Use a temp JSON file to avoid shell-escape pain with multi-line prompts.

Text-to-image

bash
cat > /tmp/gpt2_body.json << 'ENDJSON'
{
  "prompt": "A vintage diner chalkboard, hand-lettered: TODAY SPECIAL — Lobster Roll $24",
  "image_size": "landscape_4_3",
  "quality": "medium",
  "num_images": 1,
  "output_format": "png"
}
ENDJSON

curl -s -X POST "https://fal.run/openai/gpt-image-2" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d @/tmp/gpt2_body.json

Image edit

bash
cat > /tmp/gpt2_edit_body.json << 'ENDJSON'
{
  "prompt": "Same workers on the beam — but they're all on phones now. One taking a selfie.",
  "image_urls": ["https://v3b.fal.media/files/b/.../original.png"],
  "image_size": "auto",
  "quality": "medium",
  "num_images": 1,
  "output_format": "png"
}
ENDJSON

curl -s -X POST "https://fal.run/openai/gpt-image-2/edit" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d @/tmp/gpt2_edit_body.json

Prompting tips

GPT Image 2 is unusually good at typography, but you have to tell it clearly:

  • Structure complex prompts as JSON. For multi-element scenes (posters, infographics, multi-panel comics, app mockups), the model responds notably better to a JSON object than to flowing prose. Keys like type, subject, style, background, header, layout, footer give the model an explicit slot for each element. Loose prose forces it to guess what's foreground vs background. The community-curated prompt library (see "Prompt examples library" below) is almost entirely structured JSON for this reason.
  • Parameterize with placeholders for reuse. Use {argument name="quote" default="Stay hungry, stay foolish"} syntax to mark variables in your prompt. Originally a Raycast Snippets convention, widely adopted across the GPT Image 2 community. Lets one prompt template handle many variants without rewriting.
  • Quote the text: hand-lettered text reads "OPEN AT 7" — quoting helps the model lock in the literal characters.
  • Specify the lettering style: chalk lettering, serif sign painter, bold sans-serif neon, embossed metal type, cursive script.
  • Anchor the surface: chalkboard, brick wall, neon storefront, paper menu, vinyl record sleeve. The model uses the surface to inform the lettering style.
  • Mention lighting: warm tungsten, golden hour, cool fluorescent — affects mood + readability.
  • Layout hints work: the title stacked over three lines, with a small drawing below, centered.
  • For multi-line text: spell out line breaks. Line 1: "ESPRESSO". Line 2: "$4.50". Don't trust newlines in the prompt to translate.

For the edit endpoint

  • Describe the change, not the whole scene. "Same workers, same beam, same lunch boxes — but everyone is on their phone now" works better than re-describing the original from scratch.
  • Anchor to what stays the same. The model preserves more when you explicitly call out what shouldn't change.
  • Use mask_url for surgical edits. Without a mask, the model may reinterpret the whole image. With a mask, it constrains the change to the white region.
  • Chain edits. Pass the previous output URL back into a new edit call. Good for iterative refinement.

What it's bad at:

  • Long paragraphs of text — keep it to a few words/lines.
  • Faces with expressions tied to specific real people — generic figures fine, named likenesses iffy.
  • Strict style preservation in edits — it tends to reinterpret. For tight style transfer use a different model.

Transparent backgrounds — not supported

Fal's GPT Image 2 endpoints do not support true transparency. Tested 2026-04-22:

  • No background parameter (OpenAI's direct API has background: "transparent" for gpt-image-1 — Fal's wrapper for GPT Image 2 does not expose it).
  • Passing background: "transparent" anyway → silently ignored, output is RGB PNG with no alpha channel.
  • Prompting for "transparent background" → model paints a fake checkerboard pattern in the pixels. Looks transparent; isn't. The PNG is still RGB.

If you need a transparent PNG, chain a background remover:

  • fal-ai/imageutils/rembg — fast, cheap, works on most subjects.
  • fal-ai/birefnet — higher quality, slower.
  • Pass the GPT Image 2 output URL straight in as image_url.

Or use Nano Banana Pro / other models for the generation step if clean alpha matters.


Prompt examples library

For style/category inspiration, the awesome-gpt-image-2 community library has 700+ curated prompts (CC BY 4.0, attribution required). Use it whenever a user asks "how would I prompt this?" for a recognizable style or use-case.

Two ways in:

  1. Browse the gallery (humans): youmind.com/gpt-image-2-prompts — masonry grid, full-text search, deep-linkable categories.
  2. Grep the README (agents): raw.githubusercontent.com/YouMind-OpenLab/awesome-gpt-image-2/main/README.md — single markdown file, ~350KB, all prompts in one place. Predictable structure: each prompt is ### No. N: Category - Title → badges → #### 📖 Description → #### 📝 Prompt (a fenced code block, usually JSON) → #### 📌 Details (author/source/date).

Category slugs (use as ?categories={slug} on youmind.com, or as a grep target in the README):

  • Use cases: profile-avatar, social-media-post, infographic-edu-visual, youtube-thumbnail, comic-storyboard, product-marketing, ecommerce-main-image, game-asset, poster-flyer, app-web-design
  • Styles: photography, cinematic-film-still, anime-manga, illustration, sketch-line-art, comic-graphic-novel, 3d-render, chibi-q-style, isometric, pixel-art, oil-painting, watercolor, ink-chinese-style, retro-vintage, cyberpunk-sci-fi, minimalism
  • Subjects: portrait-selfie, influencer-model, character, group-couple, product, food-drink, fashion-item, animal-creature, vehicle, architecture-interior, landscape-nature, cityscape-street, diagram-chart, text-typography, abstract-background

Recipe — fetch + grep examples for a category:

bash
# Pull the README once, save locally
curl -s https://raw.githubusercontent.com/YouMind-OpenLab/awesome-gpt-image-2/main/README.md -o /tmp/gpt2_prompts.md

# Find all entries matching a category (case-insensitive)
grep -n "^### No\." /tmp/gpt2_prompts.md | grep -i "youtube thumbnail"

# Read a specific prompt block by its line range (use line numbers from the grep above)
sed -n '2722,2830p' /tmp/gpt2_prompts.md

Or, in one shot via WebFetch (for agents): fetch the raw README and ask for the N best examples in category X — the file's predictable headings make extraction reliable.

Attribution. When reusing a prompt verbatim or near-verbatim in published work, credit YouMind OpenLab + the original author (the 📌 Details section names the author and source). Repo: github.com/YouMind-OpenLab/awesome-gpt-image-2.


Notes / gotchas

  • Sync API — single POST call returns the image URL. No polling, no taskId.
  • Auth header is Key, not Bearer — Fal-specific.
  • Up to 4 images per call via num_images — useful for picking from variants. Cost scales linearly.
  • Custom dimensions: multiples of 16, total pixels in [655K, 8.3M], aspect ratio ≤ 3:1, max edge 3840px.
  • Two endpoints: /openai/gpt-image-2 (text-to-image) vs /openai/gpt-image-2/edit (with image_urls and optional mask_url). Pick by what you have as input.
  • Edit endpoint defaults image_size to auto — uses the input image's dimensions. Override only if you need a different output shape.
  • Reference images must be public URLs — upload to Fal storage, reuse a previous Fal output URL, or host elsewhere (S3, GitHub raw).
  • Fal URLs expire — download immediately.
  • sync_mode: true returns a base64 data URI inline (skips request history). Useful for piping into another tool without disk I/O. Default is false.

Links

Frequently asked questions

What does the Gpt Image 2 AI skill do?

Generate or edit images with OpenAI's GPT Image 2 (ChatGPT Images 2.0) via Fal AI. Two endpoints — text-to-image AND image edit (reference images + optional mask). Best-in-class for fine typography — chalkboards, signs, menus, posters, packaging, UI mockups, anything with legible text. Sync API, 1-4 images per call, custom dimensions up to 8.3MP. Includes pointer to a 700+ community prompt library (CC BY 4.0) for style/category inspiration. Triggers on gpt image 2, gpt-image-2, chatgpt image, openai image, typography image, sign mockup, poster mockup, menu image, packaging mockup, edit imag...

Why use Gpt Image 2 on TypingMind?

Because you install it once and use it with any model. Gpt Image 2 is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Gpt Image 2 in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/robonuggets/gpt-image-2-skill/tree/main. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Gpt Image 2?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Gpt Image 2?

As many as you like. As long as a model supports skills, you can use Gpt Image 2 with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Gpt Image 2 AI skill free?

It is published on GitHub by robonuggets. Check the repository for licensing terms. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇