AI image generation with OpenAI API
OpenAI exposes image generation through the Image API (POST /images/generations). The official openai npm package wraps it as client.images.generate. This post walks through the main request parameters and how to save generated images from Node.js.
The examples use gpt-image-2, OpenAI's latest GPT Image model. GPT Image models always return base64-encoded image data in data[].b64_json. Use output_format for the on-disk file type and put artistic direction in the prompt.
For text generation with the same package, see the Chat Completions API and Responses API posts. Image generation is also available through Responses API tools, but this post focuses on the dedicated Image API endpoint.
The running scenario: generate marketing hero images for a fictional todo app.
Prerequisites
- OpenAI account
- Generated API key
- Enabled billing
- Node.js version 26
openaipackage installed (npm i openai)
Client setup
Create a client with your API key (read from the environment in production).
import OpenAI from 'openai';const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
The same SDK can target other hosts that implement a compatible API by setting baseURL and apiKey:
const client = new OpenAI({apiKey: process.env.LLM_API_KEY,baseURL: 'https://your-gateway.example/v1',});
Azure OpenAI uses AzureOpenAI instead. Confirm your provider supports the Image API and the model you pass to model.
Basic integration
Call client.images.generate with model and prompt. The examples use gpt-image-2, older snapshots include gpt-image-1.5, gpt-image-1, and gpt-image-1-mini. Pin a snapshot (for example gpt-image-2-2026-04-21) when you need stable behavior across deploys.
The prompt describes what to generate. GPT Image models accept up to about 32,000 characters. Be specific about subject, layout, colors, and style.
GPT Image models always return base64 in data[].b64_json. Decode it and write the file yourself.
import { writeFile } from 'node:fs/promises';const prompt = `Minimal flat illustration for a productivity app landing page.Show a todo dashboard with a checklist, calendar widget, and soft pastel palette.No text labels on screen elements.`.trim();const result = await client.images.generate({model: 'gpt-image-2',prompt,});await writeFile('hero.png', Buffer.from(result.data[0].b64_json, 'base64'));
n
Use n to generate multiple images in one request (default 1, maximum 10). Loop over result.data to save each image.
import { writeFile } from 'node:fs/promises';const result = await client.images.generate({model: 'gpt-image-2',prompt:'Minimal flat illustration of a todo app dashboard, variant layout, soft pastel colors',n: 2,});for (const [index, item] of result.data.entries()) {await writeFile(`hero-${index}.png`,Buffer.from(item.b64_json, 'base64'),);}
Size
Control dimensions with size. Common presets are 1024x1024 (square), 1536x1024 (landscape), and 1024x1536 (portrait). auto lets the model pick based on the prompt.
gpt-image-2 also accepts custom WIDTHxHEIGHT strings when width and height are multiples of 16, the aspect ratio is between 1:3 and 3:1, and total pixels stay within the documented limits.
const result = await client.images.generate({model: 'gpt-image-2',prompt:'Minimal flat illustration of a todo app dashboard, portrait orientation, soft pastel colors',size: '1024x1536',});
Quality
Set rendering quality with quality. Use low for fast drafts and iterations, then medium or high for final assets. Default is auto.
const draft = await client.images.generate({model: 'gpt-image-2',prompt:'Minimal flat illustration of a todo app dashboard, soft pastel colors',quality: 'low',});const final = await client.images.generate({model: 'gpt-image-2',prompt:'Minimal flat illustration of a todo app dashboard, soft pastel colors, polished details',quality: 'high',size: '1024x1536',});
Output format
GPT Image models return base64 in the JSON response. Use output_format to control the encoded file type: png (default), jpeg, or webp.
import { writeFile } from 'node:fs/promises';const result = await client.images.generate({model: 'gpt-image-2',prompt:'Minimal flat illustration of a todo app dashboard, soft pastel colors',output_format: 'jpeg',});await writeFile('hero.jpg', Buffer.from(result.data[0].b64_json, 'base64'));
Compression
When output_format is jpeg or webp, set output_compression from 0 to 100 to trade file size for quality. JPEG is often faster than PNG when latency matters.
const result = await client.images.generate({model: 'gpt-image-2',prompt:'Minimal flat illustration of a todo app dashboard, soft pastel colors',output_format: 'webp',output_compression: 50,});
Background
Use background: 'transparent' with png or webp on models that support it when you need a cutout asset. gpt-image-2 does not support transparent backgrounds; use gpt-image-1.5 or an earlier GPT Image model for that workflow, or bake the background into the prompt.
const result = await client.images.generate({model: 'gpt-image-1.5',prompt: 'Flat icon of a checkmark, no background, centered',output_format: 'png',background: 'transparent',});
Production notes
- Cost scales with
qualityandsize. See OpenAI pricing before generating at scale. - Moderation - use
moderation: 'auto'(default) or'low'on GPT Image models when you need less restrictive filtering. - Errors - handle
image_generation_user_error(for examplemoderation_blocked) by changing the prompt or inputs; do not blindly retry. - Latency - complex prompts can take up to about two minutes.
- Storage - decode and persist files yourself. GPT Image responses are base64 in JSON.
Demo
Runnable scripts for each section live in the openai-image-generation-demo folder. Get access via code demos.