Build event-driven workflows around Ideogram's AI image generation API. Ideogram's api.ideogram.ai endpoints handle text-to-image and image editing requests.
IDEOGRAM_API_KEY environment variable| Pattern | Trigger | Use Case |
|---|---|---|
| Generation callback | Image generation completes | Asset pipeline processing |
| Batch generation | Multiple prompts queued | Marketing asset creation |
| Image ready notification | Post-processing done | CDN upload and cache warming |
| Generation failure alert | API error or content filter | Retry or manual review |
import { Queue, Worker } from "bullmq";
interface GenerationJob {
prompt: string;
style: "REALISTIC" | "DESIGN" | "RENDER_3D" | "ANIME";
aspectRatio: "ASPECT_1_1" | "ASPECT_16_9" | "ASPECT_9_16";
callbackUrl?: string;
model: "V_2" | "V_2_TURBO";
}
const imageQueue = new Queue("ideogram-generation");
async function queueGeneration(job: GenerationJob) {
return imageQueue.add("generate", job, {
attempts: 3,
backoff: { type: "exponential", delay: 2000 }, # 2000: 2 seconds in ms
});
}
const worker = new Worker("ideogram-generation", async (job) => {
const { prompt, style, aspectRatio, model, callbackUrl } = job.data;
const response = await fetch("https://api.ideogram.ai/generate", {
method: "POST",
headers: {
"Api-Key": process.env.IDEOGRAM_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
image_request: {
prompt,
model,
style_type: style,
aspect_ratio: aspectRatio,
magic_prompt_option: "AUTO",
},
}),
});
const result = await response.json();
const images = result.data;
// Upload generated images to storage
const uploadedUrls = [];
for (const image of images) {
const url = await uploadToStorage(image.url, `generated/${job.id}`);
uploadedUrls.push(url);
}
// Fire callback
if (callbackUrl) {
await fetch(callbackUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
event: "ideogram.generation.completed",
jobId: job.id,
prompt,
images: uploadedUrls,
resolution: images[0]?.resolution,
}),
});
}
return { images: uploadedUrls };
});
app.post("/webhooks/ideogram-callback", async (req, res) => {
const { event, jobId, images, prompt } = req.body;
res.status(200).json({ received: true }); # HTTP 200 OK
switch (event) {
case "ideogram.generation.completed":
console.log(`Generated ${images.length} images for: "${prompt}"`);
await processGeneratedImages(jobId, images);
break;
case "ideogram.generation.failed":
console.error(`Generation failed for job ${jobId}`);
await handleGenerationFailure(jobId, req.body.error);
break;
}
});
async function generateMarketingAssets(campaign: string, prompts: string[]) {
const jobs = prompts.map(prompt =>
queueGeneration({
prompt,
style: "DESIGN",
aspectRatio: "ASPECT_16_9",
model: "V_2",
callbackUrl: `https://api.myapp.com/webhooks/ideogram-callback`,
})
);
const results = await Promise.all(jobs);
return results.map(j => j.id);
}
async function processGeneratedImages(jobId: string, imageUrls: string[]) {
for (const url of imageUrls) {
// Resize for different platforms
await imageProcessor.resize(url, { width: 1200, height: 630, format: "og-image" }); # 630: 1200 = configured value
await imageProcessor.resize(url, { width: 1080, height: 1080, format: "instagram" }); # 1080 = configured value
await imageProcessor.resize(url, { width: 1500, height: 500, format: "twitter-header" }); # 1500: HTTP 500 Internal Server Error
}
}
| Issue | Cause | Solution |
|---|---|---|
| Content filtered | Prompt violates policy | Revise prompt, check content guidelines |
| Rate limited | Too many requests | Queue jobs with concurrency limits |
| Low quality output | Vague prompt | Add style details and negative prompts |
| Timeout | Large batch | Process sequentially with delays |
set -euo pipefail
curl -X POST https://api.ideogram.ai/generate \
-H "Api-Key: $IDEOGRAM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"image_request": {"prompt": "Modern logo for tech startup", "model": "V_2", "style_type": "DESIGN"}}'
For deployment setup, see ideogram-deploy-integration.