Image generation
Generate and edit images with gpt-image-2, save the result, and handle long requests.
Use gpt-image-2 with the Images API. Create a global API key, add USD credit, and set BEEFAPI_KEY as described in Quickstart.
1. Generate and save an image
Install the Python SDK once with python3 -m pip install openai. This example generates one image and saves the returned bytes:
import base64
import os
from pathlib import Path
from openai import OpenAI
client = OpenAI(
api_key=os.environ["BEEFAPI_KEY"],
base_url="https://global.beefapi.com/v1",
timeout=600.0,
max_retries=0,
)
result = client.images.generate(
model="gpt-image-2",
prompt="A small orange sailboat on a quiet lake, watercolor illustration",
n=1,
size="1024x1024",
response_format="b64_json",
)
image_bytes = base64.b64decode(result.data[0].b64_json)
# The returned file format can vary. Match the extension to the bytes.
if image_bytes.startswith(b"\x89PNG"):
filename = "image.png"
elif image_bytes.startswith(b"\xff\xd8\xff"):
filename = "image.jpg"
else:
filename = "image.bin"
Path(filename).write_bytes(image_bytes)
print(f"Saved {filename}")Allow several minutes for generation. Automatic retries are disabled in this example to avoid submitting a duplicate image request after an uncertain timeout.
2. View the result
Open the saved image from your working directory. The example below was generated with gpt-image-2 using the same prompt. Each generation can look different.

Prompt: A small orange sailboat on a quiet lake, watercolor illustration.
Use cURL instead
Save the JSON response, then decode the image with Python 3:
curl --fail-with-body https://global.beefapi.com/v1/images/generations \
-H "Authorization: Bearer $BEEFAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A small orange sailboat on a quiet lake, watercolor illustration",
"n": 1,
"size": "1024x1024",
"response_format": "b64_json"
}' -o image-response.jsonThis call waits for the image. Allow several minutes in your HTTP client; a client timeout does not prove generation stopped. Do not automatically submit the same image again after an ambiguous timeout.
A successful response contains created and data. Each item has b64_json or url, depending on the requested response format and model route. Save the base64 result with Python 3:
import base64
import json
from pathlib import Path
response = json.loads(Path("image-response.json").read_text())
image_bytes = base64.b64decode(response["data"][0]["b64_json"])
if image_bytes.startswith(b"\x89PNG"):
filename = "image.png"
elif image_bytes.startswith(b"\xff\xd8\xff"):
filename = "image.jpg"
else:
filename = "image.bin"
Path(filename).write_bytes(image_bytes)
print(f"Saved {filename}")With "response_format": "url", read data[0].url and download it promptly. Treat result URLs as private, potentially expiring links, not permanent hosting.
Edit an existing image
Put source.png in your current directory. Send a multipart request; curl supplies the boundary automatically:
curl --fail-with-body https://global.beefapi.com/v1/images/edits \
-H "Authorization: Bearer $BEEFAPI_KEY" \
-F 'model=gpt-image-2' \
-F 'prompt=Make the sailboat blue, preserving the composition and watercolor style' \
-F 'image=@source.png' \
-F 'n=1' \
-F 'size=1024x1024' \
-F 'response_format=b64_json' \
-o image-response.jsonSave the returned image using the same Python snippet. Start with PNG or JPEG input. Only upload images you have permission to use.
You can also send JSON with image set to a publicly accessible HTTPS image URL or a complete data:image/png;base64,... URL. Replace the example URL with your own image:
{
"model": "gpt-image-2",
"prompt": "Make the sailboat blue",
"image": "https://example.com/source.png",
"n": 1,
"response_format": "b64_json"
}Choose your parameters
| Field | Use |
|---|---|
model | Use the exact image model ID, such as gpt-image-2. |
prompt | Required description of the image or edit. |
n | Use 1. Multi-image requests are not supported on every route. |
size | Use 1024x1024 to start. Use the letter x, not the multiplication sign. Check model support before choosing another size. |
quality | Leave this out for your first request. Available options are auto, low, medium, and high; support varies by model. |
response_format | b64_json for inline image bytes, or url for a download link. |
image | Reference image for edits, sent as a multipart file, HTTPS URL, or data URL. |
Support for custom dimensions, masks, transparent backgrounds, and output formats varies by route. An accepted optional field does not guarantee that every model honors it. Keep the initial request minimal, inspect the returned image, and include the request ID when asking support about a specific option.
Optional asynchronous image jobs
Some accounts have access to image jobs. They are not available on every route that serves gpt-image-2; use the synchronous examples above unless your account supports them.
| Method | Path | Result |
|---|---|---|
| POST | /v1/images/generations/jobs | Submit the same generation JSON; HTTP 202 returns job_id and status. |
| POST | /v1/images/edits/jobs | Submit the same edit request. |
| GET | /v1/images/jobs/{job_id} | Read queued, in_progress, completed, or failed. |
| GET | /v1/images/jobs/{job_id}/result?response_format=b64_json | Read the completed result in the Images response format. |
Poll every few seconds with the same API key. Stop on completed or failed. Fetching a result before completion returns 409; a failed job includes an error. An unsupported job submission returns an error rather than silently becoming a synchronous request. After a definitive unsupported-route error, use the synchronous endpoint.
Cost and failures
Image models labeled per image on Pricing charge for generated images. Read the current USD amount from pricing.usd.json; do not infer it from text-token prices.
Check Usage after completion. For failures, keep the HTTP status, error body, request ID, and any job ID. See Billing for reserved credit and Errors for retry guidance.