Skip to main content
/blogguideby marcus rodriguez8 min read

Image and Video Generation API: FLUX, Nano Banana, Midjourney, Veo 3.1 and More From One Key

Generate images with Nano Banana, FLUX, GPT Image and Midjourney, and video with Veo 3.1 and Runway, from one API and SDK. Code, prices and pipelines.

Short answer: you can generate images and video from the same API, key and SDK you use for chat. On the LazySusan API, images.generate covers Nano Banana 2.1 and Pro, GPT Image 2.5, FLUX 3 and FLUX 2 Pro, FLUX Kontext, Midjourney V7, Stable Diffusion 3.5, Ideogram 3.0, Recraft V3, Grok Imagine and Luma Photon. videos.create covers Veo 3.1 (with native audio), Runway Gen-4.5, Luma Ray 2, Hailuo 2.3, Pika and Vidu. Images come back in one call; video runs in the background and you wait for it. You pay per image or per clip from prepaid credits, only for what's delivered, and failed videos are refunded in full.

Here's how each part works, which model to pick for which job, and a small pipeline that turns a still into a clip.

Your first image

Install the SDK (npm install lazysusan or pip install lazysusan), set LAZYSUSAN_API_KEY, and:

js
import LazySusan from "lazysusan";

const ls = new LazySusan();

const img = await ls.images.generate({
  model: "google/nano-banana-2.1",
  prompt: "A red ceramic cube on a white table, studio light",
  size: "1344x768",
});

console.log(img.images[0].url);       // a permanent hosted URL
console.log(img.usage.costCredits);   // what this image cost

In Python:

python
from lazysusan import LazySusan

ls = LazySusan()

img = ls.images.generate(
    model="bfl/flux-3",
    prompt="A red ceramic cube on a white table, studio light",
    size="1344x768",
)
print(img.images[0].url, img.cost_credits)

Every image model takes the same parameters, so switching from Nano Banana to FLUX or Midjourney is a change to model, nothing else. The parameters worth knowing:

  • size: one of the model's sizes, such as 1024x1024 (the default), 1344x768 or 768x1344. Nano Banana and FLUX map sizes to aspect ratios.
  • n: how many images. Up to 4 on Nano Banana, GPT Image and Grok Imagine; 1 on the others.
  • quality: GPT Image only, low, medium (default) or high.
  • format: url (the default, a hosted link) or b64_json for the image inline.
  • metadata: up to 16 tags, such as { campaign: "spring-launch" }, for filtering usage later.

Prompts can be up to 4,000 characters.

Which image model for which job

Image models disagree with each other far more than chat models do. A rough guide, with the per-image price in credits (1 credit = $0.001) at a standard size, from the rate card at the time of writing:

JobTry firstModel idCredits per image
Edit a photo you already haveNano Banana 2.1google/nano-banana-2.1about 39
Final, detailed assetsNano Banana Progoogle/nano-banana-proabout 154
Following long, precise instructions, text in imagesGPT Image 2.5openai/gpt-image-2.5about 6 to 48, by quality
PhotorealismFLUX 3bfl/flux-3about 55
Context-aware generationFLUX Kontext Probfl/flux-kontext-pro46
Art-directed, stylised imageryMidjourney V7midjourney/v792
Anime and illustrationNiji 6midjourney/niji-6about 58
Posters, logos, typographyIdeogram 3.0ideogram/ideogram-3see rate card
Vector icons and illustrations (SVG)Recraft V3 Vectorrecraft/recraft-v3-vector92
Cheap drafts at volumeLuma Photon Flashluma/photon-flash-1about 5
Fast, cheap variationsGrok Imaginexai/grok-imagine-image23

GPT Image models are billed by the tokens each image actually uses, so their figures are typical rather than fixed: larger sizes and higher quality use more.

The practical move is the same as with chat: draft cheap, finish expensive. Generate twenty concepts on Photon Flash or Grok Imagine, pick three, and render those on FLUX 3 or Nano Banana Pro.

Editing with reference images

Nano Banana models accept input images, which is what makes them good editors. Send one image as image, or up to three as images, as an https:// URL or a data: URL (PNG, JPEG or WebP, up to 20 MB each):

js
const edited = await ls.images.generate({
  model: "google/nano-banana-2.1",
  prompt: "Same photo, but make it golden hour and remove the cable on the left",
  image: "https://example.com/product-shot.jpg",
});
js
const combined = await ls.images.generate({
  model: "google/nano-banana-pro",
  prompt: "Put the mug from the first image on the desk from the second, matching the lighting",
  images: ["https://example.com/mug.png", "https://example.com/desk.jpg"],
});

Image URLs you send are fetched only from the public internet; private and internal addresses are refused. If you want the background on how people use Nano Banana for edits, see 9 practical ways to use Nano Banana.

What you pay for images

  • Only delivered images. Ask for 4 and get 3 back, and you pay for 3.
  • Declined prompts are free. If no image comes back, for example because a safety filter declined the prompt, the request returns a 400 and costs nothing.
  • Hosted URLs are permanent and unguessable. Anyone with the link can open it, so treat it like a share link. If you need access control, download the file and re-host it.

Video: start it, then wait for it

Video takes from about a minute to a few minutes, so it doesn't fit in one HTTP request. videos.create starts the job and returns straight away; videos.wait polls until it's done and returns the finished video, or raises an error if it failed.

js
const v = await ls.videos.create({
  model: "google/veo-3.1-fast",
  prompt: "A slow pan across a calm lake at sunrise. Sound: birds, light wind.",
  seconds: 8,
  resolution: "1080p",
  aspectRatio: "16:9",
  metadata: { campaign: "spring-launch" },
});

const done = await ls.videos.wait(v.id);
console.log(done.videoUrl, done.costCredits);

In a web app, you usually don't want a request handler sitting in wait. Store v.id, return to the user, and check later with ls.videos.get(id), or let a background worker do the waiting. Videos finish even if nobody is waiting, and ls.videos.list() returns your 50 most recent.

The video parameters:

  • seconds: one of the model's durations (default: the shortest).
  • resolution: one of the model's resolutions. Veo renders 1080p only at 8 seconds.
  • aspectRatio: 16:9 (default) or 9:16; some models offer more.
  • image: a starting frame. Required for runway/gen-4-turbo and vidu/viduq2-turbo.
  • negativePrompt: Google Veo models only, up to 1,000 characters.

Which video model for which job

Clip prices in credits at the time of writing; the rate card has every length and resolution.

JobModel idAudioExample clip price
Final clip with synced soundgoogle/veo-3.1yes3,680 for 8 s
Most social clips, with soundgoogle/veo-3.1-fastyes920 for 8 s at 720p
Cheap drafts with soundgoogle/veo-3.1-liteyes460 for 8 s at 720p
Cinematic motion and camera movesrunway/gen-4.5no690 for 5 s
Animate a still, cheaplyrunway/gen-4-turbono287.5 for 5 s
People and expressionsminimax/hailuo-2.3no322 for 6 s at 768p
Smooth camera motion, many aspect ratiosluma/ray-2no460 for 5 s at 540p
Stylised social clipspika/pika-2.5no460 for 5 s at 540p
Fast, low-cost image to videovidu/viduq2-turbono80.5 for 5 s at 540p

If you're coming from the Sora API, which OpenAI switched off on September 24, Veo 3.1 is the closest match: one prompt in, a clip with sound out. There's a longer comparison in Sora is shut down: what to use instead.

How video billing works

  • Starting a video holds its exact price from your balance while it renders (costCreditsHeld).
  • On success, you're charged that amount.
  • On failure, the status is failed, error.message says why, and the hold is returned in full.
  • A video that hasn't finished after 2 hours is marked failed and refunded.

Because the price is fixed per clip, you can show users the cost before they press generate.

A small pipeline: still image to animated clip

Generating a strong first frame with an image model, then animating it, gives you far more control over composition than text-to-video alone:

js
import LazySusan from "lazysusan";

const ls = new LazySusan();
const tags = { campaign: "spring-launch" };

// 1. Draft four cheap concepts
const drafts = await ls.images.generate({
  model: "xai/grok-imagine-image",
  prompt: "Ceramic coffee mug on a sunlit kitchen counter, steam rising, editorial photo",
  n: 4,
  metadata: tags,
});

// 2. Re-render the chosen concept at full quality
const hero = await ls.images.generate({
  model: "bfl/flux-3",
  prompt: "Ceramic coffee mug on a sunlit kitchen counter, steam rising, editorial photo, 35mm",
  size: "1344x768",
  metadata: tags,
});

// 3. Animate it
const clip = await ls.videos.create({
  model: "runway/gen-4-turbo",
  prompt: "Steam curls upward, slow push in",
  image: hero.images[0].url,
  seconds: 5,
  metadata: tags,
});

const done = await ls.videos.wait(clip.id);
console.log(done.videoUrl);

Because every step carries the same campaign tag, the console can show you exactly what that campaign cost across both endpoints.

Keep keys on the server

One rule that matters more for media than for chat: generation is usually triggered from a front end, and it's tempting to call the API straight from the browser. Don't. Keep the key on your server, expose your own endpoint, and enforce your own per-user limits there. On the LazySusan side, give the service its own key with a monthly budget and an allowlist of the models you actually use, as described in setting AI API budgets per project and environment.

Not building anything?

If you want to make images and video by hand rather than in code, the same models (plus a few that are app-only, such as ElevenLabs voice) are in the LazySusan app. The models page lists them and pricing has the app plans, which are separate from API credits.


FAQ

Is there one API for both image and video generation? Yes. The LazySusan API uses one key and one SDK for chat, image and video models: images.generate for images and videos.create plus videos.wait for video.

Can I use Veo 3.1 through an API? Yes. Use the model id google/veo-3.1, google/veo-3.1-fast or google/veo-3.1-lite with videos.create. Veo clips include generated audio.

Can I use FLUX and Midjourney models through the same API? Yes. FLUX 3, FLUX 2 Pro, FLUX Kontext and FLUX 1.1 models, and Midjourney V7, V6.1, V6 and Niji 6, all use the same images.generate call. Change the model id to switch.

Am I charged if a video fails? No. The clip price is held while it renders and returned in full if it fails, including videos that haven't finished after 2 hours.

How long do generated images and videos stay available? The hosted URLs are permanent and unguessable. Anyone with a link can open it, so download and re-host files if you need to control access.

get started

Stop juggling AI subscriptions.

ChatGPT, Claude, Gemini, Grok and the leading image, video and voice models in one workspace.

Starter is $8/month. Cancel anytime.