# How to Generate Animated GIFs and SVG Icons with the OpenAI Images 2.6 API in Python

> Source: <https://pub.towardsai.net/how-to-generate-animated-gifs-and-svg-icons-with-the-openai-images-2-6-api-in-python-8aeac5285d71?source=rss----98111c9905da---4>
> Published: 2026-11-09 20:01:01+00:00

One short script, two new output formats, and the two errors I hit so you don’t have to.

Follow me on 🔗[LinkedIn](https://www.linkedin.com/in/prajwal-waykos/), 🐙GitHub: [https://github.com/praj-17](https://github.com/praj-17)

Images 2.6 can now return an animated GIF or a real vector SVG straight from client.images.generate. Set output_format=”gif” with frame_count and frame_duration_ms, or set output_format=”svg” with an svg={“model”: …} object. Both come back as base64 in data[0].b64_json. My 6 frame GIF took 13.4 seconds and cost about 2.7 cents. My SVG icon took 20.1 seconds and cost about 4.1 cents.

Here is the whole idea in one snippet.

``` python
import base64from openai import OpenAIclient = OpenAI()  # reads OPENAI_API_KEYgif = client.images.generate(    model="gpt-image-2.6-flare",    prompt="A cute cartoon coffee cup with steam swirling above it. Seamless loop.",    output_format="gif",    frame_count=6,    frame_duration_ms=150,    size="768x768",    quality="low",)open("coffee_loop.gif", "wb").write(base64.b64decode(gif.data[0].b64_json))
```

That’s it. The rest of this post is what each knob does, what broke, and what it really cost.

Imagine asking a designer for “a small looping animation and an app icon, by lunch, for free.” They would laugh and go back to their coffee.

So I made the coffee do the work instead. Every Sunday I pick one new API and build the smallest useful thing with it. This week OpenAI shipped Images 2.6 on November 4, and two features jumped out at me. It can now make GIFs, and it can export SVGs. I have spent more hours than I’d like to admit wrestling with sprite sheets and tracing PNGs into vectors, so I wanted to see if one Python file could replace all of that.

*If computers could talk, they’d ask for faster processors. Mine asked for a smaller frame size.*

You only need a few things before we start.

2) The official SDK. I used openai 3.46.0, the newest release when I wrote this. Older versions may not know about frame_count or svg, so pin a version that supports them.

3) An OpenAI API key in the OPENAI_API_KEY environment variable.

4) Possibly a verified organization. The docs warn that GPT Image models can require API Organization Verification, and the API reference says GIF output needs access to the GIF preview for the model. My key worked out of the box, but yours might not.

```
python3 -m venv .venv && source .venv/bin/activatepip install "openai>=3.46.0"export OPENAI_API_KEY=sk-...
```

There are two models in the API, and the names sound like energy drinks.

gpt-image-2.6-flare is the fast one. OpenAI says it can produce an image in as little as six seconds at low quality. gpt-image-2.6-sunburst is the careful one, built for more detail and better consistency across edits at medium or high quality.

Both cost the same per token. Text input is $5 per million tokens, image input is $8 per million, and image output is $30 per million. For a tutorial and quick drafts, Flare is the obvious choice, so that’s what I used everywhere below.

Both models work with only two endpoints, /v1/images/generations and /v1/images/edits. You can’t call them from the Responses API.

Let’s break it down. You send one normal images.generate call with output_format=”gif”. The API does all the animation work on its side and sends back one finished GIF file, base64 encoded. There’s no frame stitching on your side and no Pillow required.

Three fields control the animation. frame_count sets how many frames you get. It accepts 2 to 16 and defaults to 9.

frame_duration_ms sets how long each frame stays on screen. The guide allows 20 to 2000 milliseconds, rounded to the nearest 10, with a default of 200.

size sets the size of each frame, not the whole file. Use auto or a WIDTHxHEIGHT where both numbers are multiples of 16.

Notice what is missing. There is no fps field, so you do the maths yourself.

150 ms per frame is about 6.7 frames per second. There is also no loop field.

The docs simply tell you to describe the loop in your prompt, so I wrote “the last frame flows back into the first.”

GIF output doesn’t support streaming, partial images, masks, or output_compression, so leave those out.

I asked for six frames at 1024x1024 and got this back.

```
openai.BadRequestError: Error code: 400 - No supported sheet fits 6 GIF framesat size "1024x1024". Invalid size "4096x2048". The longest edge must be lessthan or equal to 3840.
```

This error is the most useful thing I learned all week. It tells you how GIFs are made behind the scenes. The model paints all the frames onto one big sprite sheet, then cuts it up. Six frames went into a 4 by 2 grid, and four frames of 1024 pixels is 4096, which is over the 3840 pixel limit for an edge.

The docs only say the frames must fit the model’s size limits and the total request pixel budget, without publishing the exact numbers. So here’s a rule of thumb that worked for me. Roughly, frames across times frame width has to stay at or under 3840. At 768x768, a 4 by 2 sheet is 3072 by 1536, and it went through first try.

Here’s the complete file. It makes the GIF, then the SVG, times both, and saves the token usage so you can work out the cost.

``` python
"""Make a 6-frame looping GIF and an SVG icon with OpenAI Images 2.6."""import base64, json, os, sys, timefrom pathlib import Pathfrom openai import OpenAIMODEL = os.getenv("IMAGE_MODEL", "gpt-image-2.6-flare")SVG_AUTHOR = os.getenv("SVG_MODEL", "gpt-6.1-sol")  # writes the SVG codeOUT = Path(__file__).parent / "outputs"OUT.mkdir(exist_ok=True)if not os.getenv("OPENAI_API_KEY"):    sys.exit("Set OPENAI_API_KEY first.")client = OpenAI()def run(label, name, **params):    start = time.perf_counter()    result = client.images.generate(model=MODEL, **params)    seconds = time.perf_counter() - start    path = OUT / name    path.write_bytes(base64.b64decode(result.data[0].b64_json))    usage = result.usage.model_dump() if result.usage else None    if getattr(result, "svg_usage", None):        usage = {"image": usage, "svg": result.svg_usage.model_dump()}    print(f"{label}: {path} ({path.stat().st_size / 1024:.1f} KB) in {seconds:.1f}s")    return {"file": str(path), "seconds": round(seconds, 2), "usage": usage}report = {"model": MODEL}report["gif"] = run(    "GIF", "coffee_loop.gif",    prompt=("A cute cartoon coffee cup with a happy face, steam rising and swirling "            "above it. Smooth seamless loop: the last frame flows back into the first. "            "Flat pastel colors, plain cream background, no text."),    output_format="gif", frame_count=6, frame_duration_ms=150,    size="768x768", quality="low",)report["svg"] = run(    "SVG", "coffee_icon.svg",    prompt=("A minimal flat app icon of a coffee cup with three steam lines. "            "Two colors, bold simple shapes, rounded corners, no text."),    output_format="svg", n=1, quality="low", svg={"model": SVG_AUTHOR},)(OUT / "report.json").write_text(json.dumps(report, indent=2))
```

Running it printed this.

```
GIF: outputs/coffee_loop.gif (719.6 KB) in 13.3sSVG: outputs/coffee_icon.svg (1.5 KB) in 20.1s
```

I didn’t want to trust my eyes alone, so I opened the file with Pillow.

``` python
from PIL import Imageim = Image.open("outputs/coffee_loop.gif")print(im.size, im.n_frames, im.info.get("loop"))# (768, 768) 6 0
```

It has exactly 6 frames at 768x768, and every frame is 150 ms long. loop is 0, which in GIF language means “loop forever.” So the API sets infinite looping for you even though there’s no parameter for it. Nice.

The cup stays nearly identical across frames, and only the steam moves, which is exactly what a loop should do. The file is 720 KB, which is chunky for a 1 second animation. If you’re putting it on a website, convert it to WebP or MP4 afterwards, or ask for fewer frames.

This one surprised me. My first SVG call failed with a very short message.

```
openai.BadRequestError: Error code: 400 - SVG generation requires 'svg.model'.
```

The guide’s SVG section doesn’t mention this at all. The API reference does, though. When your account has SVG model selection enabled, you must pass an svg object naming the model that writes the SVG. The reference doesn’t list which models are allowed. I passed gpt-6.1-sol, and it worked.

Here’s an easy way to think about it. The image model first paints a normal picture as a reference. Then a second, text model looks at that picture and writes SVG code by hand, like a very fast illustrator tracing it. That’s why the response carries a separate svg_usage block, and that’s why SVG took longer than the GIF.

A few rules apply. n must be 1. SVG works only on the generate endpoint, not edits. You can’t use streaming or compression. The output is plain static vector content, with no scripts, external files, or embedded images, so it’s safe to drop into a web page.

I parsed it with Python’s built in XML parser, and it loaded cleanly. It’s a 1,254 by 1,254 viewBox with a title, a rounded background rect, and neatly named paths with ids like steam, saucer, handle, and cup. That’s 10 elements and 1.5 KB in total. You can open it in any editor and change the brown to your brand colour in five seconds.

Medium doesn’t accept SVG uploads, so I converted it to PNG with one line of cairosvg.

``` python
import cairosvgcairosvg.svg2png(url="outputs/coffee_icon.svg", write_to="icon.png", output_width=800)
```

Pricing is per token, not per image, so I worked it out from the usage each call returned.

Call — Tokens — Cost

GIF, image model — 69 text in, 903 image out — about $0.0274

SVG, image model — 99 text in, 962 image out — about $0.0294

SVG, author model (gpt-6.1-sol) — 2,300 in, 730 out — about $0.0119

That comes to roughly 2.7 cents for the GIF and 4.1 cents for the icon. For the SVG author I used gpt-6.1-sol’s standard rate of $2 per million input tokens and $10 per million output tokens.

Interesting detail: the six frame GIF used fewer output tokens than you’d guess for six images. That matches the sprite sheet idea from the error earlier, since the frames are painted together rather than one by one.

1 — GIF and SVG are just new values for output_format. Everything else is the same images.generate call you already know.

2 — size means one frame. Multiply by the sheet layout before you go big, or you’ll meet the 3840 pixel error.

3 — There’s no loop setting, but the file came back with infinite looping anyway. Still describe the loop in your prompt so the last frame matches the first.

4 — SVG is really two models working in a row, so check svg_usage or your cost maths will be wrong.

5 — If you see “requires svg.model”, add svg={model: …}. The guide doesn’t say it, but the API reference does.

6 — Start with Flare at quality low while you iterate on prompts. Move to Sunburst or higher quality only for the final asset.

7 — GIFs are big. Plan on converting them for the web.

Remember, the only limit is your imagination (and maybe your 3840 pixel edge).

In under 40 seconds and less than 7 cents, one small script gave me a looping animation and an editable vector icon. Before this, that would have taken me an afternoon of sprite sheets and tracing tools. Now, go unleash that creative beast and build something awesome!

What would you animate first, a mascot, a loading spinner, or your morning coffee? Tell me in the comments.

Image generation guide: [https://developers.openai.com/api/docs/guides/image-generation?model=gpt-image-2.6](https://developers.openai.com/api/docs/guides/image-generation?model=gpt-image-2.6)

Images generate API reference: [https://developers.openai.com/api/reference/resources/images/methods/generate](https://developers.openai.com/api/reference/resources/images/methods/generate)

gpt-image-2.6-flare model page: [https://developers.openai.com/api/docs/models/gpt-image-2.6-flare](https://developers.openai.com/api/docs/models/gpt-image-2.6-flare)

**Happy coding! If you have any questions or suggestions, feel free to leave a comment.**

[How to Generate Animated GIFs and SVG Icons with the OpenAI Images 2.6 API in Python](https://pub.towardsai.net/how-to-generate-animated-gifs-and-svg-icons-with-the-openai-images-2-6-api-in-python-8aeac5285d71) was originally published in [Towards AI](https://pub.towardsai.net) on Medium, where people are continuing the conversation by highlighting and responding to this story.
