The Three IDs on the Deadline
Google's release notes announced the deprecation on June 15. Its deprecations table, last updated August 13, lists an August 17 shutdown date for all three stable Imagen 4 endpoints:
imagen-4.0-generate-001imagen-4.0-ultra-generate-001imagen-4.0-fast-generate-001
For each one, the table recommends gemini-3.1-flash-image. Google describes shutdown dates in that table as the earliest date on which a model may be retired, so the operationally safe interpretation is a deadline, not a promise that the old endpoint will work through the end of August 17.
Finding the three model strings is necessary, but it is not a complete inventory. Search for generateImages, :predict, generatedImages, imageBytes, sampleCount, and any internal type named after Imagen. Those are the places where the old API contract can survive after the model id has disappeared.
Why a Direct String Swap Fails
Google's Imagen JavaScript example calls ai.models.generateImages() and reads bytes from response.generatedImages[].image.imageBytes. Its REST example calls .../models/imagen-4.0-generate-001:predict with instances and parameters. The current Gemini native-image guide instead uses the Interactions API and exposes generated bytes through output_image. Google's legacy Generate Content examples use another shape again: inlineData among returned content parts.
Those differences affect more than parsing. Imagen's documented options include a batch count and Imagen-specific person-generation controls. Gemini native image generation has its own response-modality and image-format configuration. Do not assume an option with a similar name has identical defaults or policy behavior. First choose one supported Gemini API surface for the migration, then make your application depend on an internal image result rather than the provider response object.
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({});
export async function generateImage(prompt) {
const interaction = await ai.interactions.create({
model: "gemini-3.1-flash-image",
input: prompt,
response_format: {
type: "image",
mime_type: "image/png",
aspect_ratio: "16:9",
image_size: "1K"
}
});
const image = interaction.output_image;
if (!image?.data) {
throw new Error("No image returned by the Gemini interaction");
}
return {
bytes: Buffer.from(image.data, "base64"),
mimeType: image.mime_type ?? "application/octet-stream"
};
}
This adapter follows Google's current Interactions API example and deliberately returns only the two fields the next layer needs. Keep provider metadata separately for diagnostics. If your application needs several candidates, make that an explicit orchestration decision and define whether one failed generation fails the whole batch; do not carry Imagen's old batch assumptions into the new adapter invisibly.
Prove the Binary Contract First
A successful HTTP status does not prove that downstream code received a usable image. Run a small contract suite against the new adapter before any visual comparison. For every accepted response, verify that decoded bytes are non-empty, the declared MIME type is on your allowlist, the file signature agrees with that MIME type, your decoder can open the image, and the decoded dimensions meet the product's layout rule. Store the provider request id and finish reason when available so a missing-image failure can be traced without logging the user's prompt by default.
Then exercise failures on purpose. Use a request your policy layer rejects, a forced timeout, an invalid aspect-ratio setting, and a response fixture with text but no image part. The adapter should return a typed failure in each case rather than an empty buffer, a corrupt file, or a generic success object. If your job system retries generation, confirm that one logical job cannot write two competing assets after a timeout.
Also test the storage boundary. Write a generated image through the same upload path production uses, retrieve it again, decode it, and compare a checksum of the stored bytes with the adapter output. This catches a migration that works in a notebook but fails when MIME validation, file extensions, resizing, or object-storage metadata enter the path.
Pixel Equality Is the Wrong Acceptance Test
Generative image output is not deterministic enough for a golden-image byte comparison. Build a compact prompt set from real production demands instead: one layout with reserved copy space, one scene with multiple named objects, one brand-sensitive palette, one difficult aspect ratio, and one prompt that should be refused or constrained. Keep prompts and evaluation criteria fixed while you compare the old and new paths.
For each sample, record whether the required subjects exist, whether their spatial relationship is correct, whether text-safe space remains usable, whether the crop survives your responsive variants, and whether a human reviewer would accept the result for the intended surface. Measure latency and failure rate separately. A visually acceptable replacement that doubles queue time is still a production change; a faster replacement that loses required composition is not a successful migration.
For example, if a 16:9 homepage image needs its rightmost 30% clear for a title overlay, encode that as an acceptance rule and inspect the same crop at both desktop and 760-pixel widths. "Looks good" cannot catch the named failure mode: a subject that moves into the copy area after the model change.
A Cutover You Can Still Reverse
- Inventory today. Find the three model ids and every old request, response, batching, retry, storage, and logging assumption attached to them.
- Add a provider-neutral adapter. Keep the current Imagen path and the new Gemini path behind the same application contract while both endpoints are available.
- Run the binary and failure suites. Stop if extraction, MIME checks, decoding, dimensions, storage, or retry behavior differs from the contract.
- Evaluate a fixed prompt set. Compare product requirements, not exact pixels, and save the decision evidence with the migration.
- Canary real traffic. Route a small, observable slice to the new adapter. Track missing-image responses, policy blocks, decode failures, latency, and storage errors by provider path.
- Switch before August 17. Keep the old adapter as a rollback only while the old endpoint is actually available. After shutdown, rollback means disabling generation or using a separately tested fallback, not pointing traffic back at Imagen 4.
Once the new path is stable, remove Imagen-only configuration and response types. Leaving dead model ids in environment templates or disaster-recovery code turns the next incident into archaeology. For the broader lifecycle pattern, see our guide to model availability risk and the model fallback drill.