Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Migrate between Ideogram API versions (V_1 to V_2 to V3) with breaking change detection. Use when upgrading from legacy to V3 endpoints, updating model versions, or handling deprecated API parameters. Trigger with phrases like "upgrade ideogram", "ideogram migration", "ideogram v2 to v3", "ideogram breaking changes", "migrate ideogram API".
.claude/skills/jeremylongshore-ideogram-upgrade-migration/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 25% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 7% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -2% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 64% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 119% | 0% |
!npm list 2>/dev/null | head -10
Guide for migrating between Ideogram API versions. The primary migration path is from the legacy /generate endpoint (JSON body, V_1/V_2 models) to the V3 endpoints (multipart form data, new parameters). This covers breaking changes in request format, model names, aspect ratio syntax, style types, and new capabilities.
| Aspect | Legacy (/generate) | V3 (/v1/ideogram-v3/generate) | |--------|---------------------|--------------------------------| | Content-Type | application/json | multipart/form-data | | Body format | { "image_request": { ... } } | FormData fields | | Models | V_1, V_1_TURBO, V_2, V_2_TURBO, V_2A | Implicit V3 (no model field) | | Aspect ratio | ASPECT_16_9 | 16x9 | | Style types | AUTO, GENERAL, REALISTIC, DESIGN, RENDER_3D, ANIME | AUTO, GENERAL, REALISTIC, DESIGN, FICTION | | Magic prompt | magic_prompt_option | magic_prompt | | New in V3 | -- | rendering_speed, style_preset, style_codes, character_reference_images | | Color palette | Preset name or hex array | Same, with weight support |
bashset -euo pipefail # Find all Ideogram API calls in your codebase grep -rn "api.ideogram.ai" --include="*.ts" --include="*.js" --include="*.py" . grep -rn "ASPECT_" --include="*.ts" --include="*.js" . grep -rn "image_request" --include="*.ts" --include="*.js" . grep -rn "magic_prompt_option" --include="*.ts" --include="*.js" .
typescript// src/ideogram/adapter.ts interface GenerateOptions { prompt: string; style?: string; aspectRatio?: string; negativePrompt?: string; seed?: number; renderingSpeed?: string; // V3 only stylePreset?: string; // V3 only } const API_KEY = process.env.IDEOGRAM_API_KEY!; const USE_V3 = process.env.IDEOGRAM_API_VERSION === "v3"; async function generateImage(options: GenerateOptions) { return USE_V3 ? generateV3(options) : generateLegacy(options); } // Legacy endpoint -- JSON body async function generateLegacy(options: GenerateOptions) { const response = await fetch("https://api.ideogram.ai/generate", { method: "POST", headers: { "Api-Key": API_KEY, "Content-Type": "application/json" }, body: JSON.stringify({ image_request: { prompt: options.prompt, model: "V_2", style_type: options.style ?? "AUTO", aspect_ratio: options.aspectRatio ?? "ASPECT_1_1", magic_prompt_option: "AUTO", negative_prompt: options.negativePrompt, seed: options.seed, }, }), }); if (!response.ok) throw new Error(`Legacy generate: ${response.status}`); return response.json(); } // V3 endpoint -- multipart form data async function generateV3(options: GenerateOptions) { const form = new FormData(); form.append("prompt", options.prompt); form.append("style_type", mapStyleToV3(options.style ?? "AUTO")); form.append("aspect_ratio", mapAspectRatioToV3(options.aspectRatio ?? "ASPECT_1_1")); form.append("magic_prompt", "AUTO"); form.append("rendering_speed", options.renderingSpeed ?? "DEFAULT"); if (options.negativePrompt) form.append("negative_prompt", options.negativePrompt); if (options.seed) form.append("seed", String(options.seed)); if (options.stylePreset) form.append("style_preset", options.stylePreset); const response = await fetch("https://api.ideogram.ai/v1/ideogram-v3/generate", { method: "POST", headers: { "Api-Key": API_KEY }, body: form, }); if (!response.ok) throw new Error(`V3 generate: ${response.status}`); return response.json(); }
typescriptfunction mapAspectRatioToV3(legacy: string): string { const map: Record<string, string> = { "ASPECT_1_1": "1x1", "ASPECT_16_9": "16x9", "ASPECT_9_16": "9x16", "ASPECT_3_2": "3x2", "ASPECT_2_3": "2x3", "ASPECT_4_3": "4x3", "ASPECT_3_4": "3x4", "ASPECT_10_16": "10x16", "ASPECT_16_10": "16x10", "ASPECT_1_3": "1x3", "ASPECT_3_1": "3x1", }; return map[legacy] ?? legacy; // Pass through if already V3 format } function mapStyleToV3(legacy: string): string { const map: Record<string, string> = { "AUTO": "AUTO", "GENERAL": "GENERAL", "REALISTIC": "REALISTIC", "DESIGN": "DESIGN", "RENDER_3D": "GENERAL", // No V3 equivalent -- use GENERAL "ANIME": "FICTION", // V3 renamed to FICTION }; return map[legacy] ?? "GENERAL"; }
typescript// Gradual migration with feature flag function shouldUseV3(userId?: string): boolean { // Phase 1: Internal testing if (process.env.IDEOGRAM_FORCE_V3 === "true") return true; // Phase 2: Percentage rollout if (userId) { const hash = Array.from(userId).reduce((h, c) => h * 31 + c.charCodeAt(0), 0); const percentage = parseInt(process.env.IDEOGRAM_V3_PERCENTAGE ?? "0"); return (Math.abs(hash) % 100) < percentage; } return false; }
typescript// Run both endpoints and compare results async function validateMigration(prompt: string) { const [legacy, v3] = await Promise.all([ generateLegacy({ prompt, style: "REALISTIC", aspectRatio: "ASPECT_16_9" }), generateV3({ prompt, style: "REALISTIC", aspectRatio: "ASPECT_16_9" }), ]); console.log("Legacy:", { resolution: legacy.data[0].resolution, seed: legacy.data[0].seed }); console.log("V3:", { resolution: v3.data[0].resolution, seed: v3.data[0].seed }); console.log("Both returned images:", legacy.data.length > 0 && v3.data.length > 0); }
After migration, you gain access to:
FLASH, TURBO, DEFAULT, QUALITYOIL_PAINTING, WATERCOLOR, POP_ART, JAPANDI_FUSION, etc.| Issue | Cause | Solution | |-------|-------|----------| | RENDER_3D fails in V3 | Removed from V3 style types | Map to GENERAL | | ANIME fails in V3 | Renamed to FICTION | Update enum mapping | | JSON body rejected by V3 | V3 requires multipart form | Switch to FormData | | magic_prompt_option ignored | V3 uses magic_prompt | Update field name | | model field in V3 | V3 has no model field | Remove from V3 requests |
For CI integration during upgrades, see ideogram-ci-integration.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 33,850 | 35,992 | +6% | 1 | 1 | 0% | 7,583 | 9,509 | +25% | 0 | 0 | — |
case-02 | fail→pass | 35,059 | 47,275 | +35% | 1 | 1 | 0% | 6,920 | 7,396 | +7% | 0 | 0 | — |
case-03 | fail→pass | 43,948 | 33,017 | -25% | 1 | 1 | 0% | 8,260 | 8,106 | -2% | 0 | 0 | — |
case-04 | fail→pass | 17,749 | 16,082 | -9% | 1 | 1 | 0% | 2,938 | 4,831 | +64% | 0 | 0 | — |
case-05 | fail→pass | 12,903 | 10,677 | -17% | 1 | 1 | 0% | 1,533 | 3,353 | +119% | 0 | 0 | — |
case-06 | fail→pass | 16,102 | 7,354 | -54% | 1 | 1 | 0% | 2,514 | 3,694 | +47% | 0 | 0 | — |
case-07 | fail→pass | 46,637 | 10,835 | -77% | 1 | 1 | 0% | 2,742 | 4,554 | +66% | 0 | 0 | — |
case-08 | fail→pass | 24,722 | 11,454 | -54% | 1 | 1 | 0% | 1,871 | 3,562 | +90% | 0 | 0 | — |
case-09 | fail→pass | 17,804 | 17,140 | -4% | 1 | 1 | 0% | 2,556 | 4,212 | +65% | 0 | 0 | — |
case-10 | fail→pass | 6,237 | 9,759 | +56% | 1 | 1 | 0% | 1,078 | 3,096 | +187% | 0 | 0 | — |
case-11 | fail→fail | 21,495 | 9,495 | -56% | 1 | 1 | 0% | 3,095 | 2,988 | -3% | 0 | 0 | — |
case-12 | fail→pass | 24,370 | 7,914 | -68% | 1 | 1 | 0% | 3,355 | 2,786 | -17% | 0 | 0 | — |
case-13 | fail→pass | 16,786 | 13,055 | -22% | 1 | 1 | 0% | 2,620 | 3,936 | +50% | 0 | 0 | — |
case-18 | fail→pass | 18,065 | 11,606 | -36% | 1 | 1 | 0% | 2,691 | 4,649 | +73% | 0 | 0 | — |
case-14 | pass→pass | 17,113 | 14,235 | -17% | 1 | 1 | 0% | 2,466 | 4,425 | +79% | 0 | 0 | — |
case-15 | fail→pass | 20,231 | 17,706 | -12% | 1 | 1 | 0% | 3,074 | 4,748 | +54% | 0 | 0 | — |
case-16 | fail→pass | 16,972 | 10,442 | -38% | 1 | 1 | 0% | 2,066 | 3,263 | +58% | 0 | 0 | — |
case-17 | fail→pass | 16,181 | 13,580 | -16% | 1 | 1 | 0% | 2,146 | 3,981 | +86% | 0 | 0 | — |
case-19 | fail→pass | 27,547 | 21,450 | -22% | 1 | 1 | 0% | 3,608 | 7,346 | +104% | 0 | 0 | — |
case-20 | pass→pass | 13,924 | 8,840 | -37% | 1 | 1 | 0% | 1,926 | 3,631 | +89% | 0 | 0 | — |
case-21 | pass→pass | 13,850 | 6,281 | -55% | 1 | 1 | 0% | 1,803 | 3,590 | +99% | 0 | 0 | — |
case-22 | fail→pass | 16,366 | 10,948 | -33% | 1 | 1 | 0% | 2,139 | 3,455 | +62% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +82 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.