Configure Ideogram local development with mock responses and testing. Use when setting up a development environment, configuring test workflows, or establishing a fast iteration cycle with Ideogram. Trigger with phrases like "ideogram dev setup", "ideogram local development", "ideogram dev environment", "develop with ideogram", "ideogram testing".
64
77%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./plugins/saas-packs/ideogram-pack/skills/ideogram-local-dev-loop/SKILL.mdSet up a fast local development workflow for Ideogram integrations. Includes a typed client wrapper, mock server for offline development (avoids burning credits), and vitest integration for automated testing.
ideogram-install-auth setupIDEOGRAM_API_KEY environment variable setmy-ideogram-project/
├── src/
│ ├── ideogram/
│ │ ├── client.ts # Typed Ideogram client wrapper
│ │ ├── types.ts # Request/response type definitions
│ │ └── mock-server.ts # Local mock for offline dev
│ └── index.ts
├── tests/
│ └── ideogram.test.ts
├── .env.local # Local secrets (git-ignored)
├── .env.example # Template for team
├── tsconfig.json
└── package.jsonset -euo pipefail
npm install dotenv
npm install -D typescript tsx vitest @types/node// src/ideogram/types.ts
export type StyleType = "AUTO" | "GENERAL" | "REALISTIC" | "DESIGN" | "RENDER_3D" | "ANIME";
export type AspectRatio = "ASPECT_1_1" | "ASPECT_16_9" | "ASPECT_9_16" | "ASPECT_3_2" | "ASPECT_2_3"
| "ASPECT_4_3" | "ASPECT_3_4" | "ASPECT_10_16" | "ASPECT_16_10" | "ASPECT_1_3" | "ASPECT_3_1";
export type Model = "V_1" | "V_1_TURBO" | "V_2" | "V_2_TURBO" | "V_2A" | "V_2A_TURBO";
export type MagicPrompt = "AUTO" | "ON" | "OFF";
export interface GenerateRequest {
prompt: string;
model?: Model;
style_type?: StyleType;
aspect_ratio?: AspectRatio;
magic_prompt_option?: MagicPrompt;
negative_prompt?: string;
num_images?: number;
seed?: number;
}
export interface ImageResult {
url: string;
prompt: string;
resolution: string;
is_image_safe: boolean;
seed: number;
style_type: StyleType;
}
export interface GenerateResponse {
created: string;
data: ImageResult[];
}// src/ideogram/client.ts
import type { GenerateRequest, GenerateResponse } from "./types";
const IDEOGRAM_API = "https://api.ideogram.ai";
export class IdeogramClient {
constructor(private apiKey: string) {
if (!apiKey) throw new Error("IDEOGRAM_API_KEY is required");
}
async generate(request: GenerateRequest): Promise<GenerateResponse> {
const response = await fetch(`${IDEOGRAM_API}/generate`, {
method: "POST",
headers: {
"Api-Key": this.apiKey,
"Content-Type": "application/json",
},
body: JSON.stringify({ image_request: request }),
});
if (!response.ok) {
const body = await response.text();
throw new IdeogramError(response.status, body);
}
return response.json();
}
}
export class IdeogramError extends Error {
constructor(public status: number, public body: string) {
super(`Ideogram API error ${status}: ${body}`);
this.name = "IdeogramError";
}
}// src/ideogram/mock-server.ts
import type { GenerateResponse } from "./types";
// Use this in development to avoid burning real credits
export function mockGenerate(prompt: string): GenerateResponse {
return {
created: new Date().toISOString(),
data: [{
url: `https://placehold.co/1024x1024/333/fff?text=${encodeURIComponent(prompt.slice(0, 30))}`,
prompt,
resolution: "1024x1024",
is_image_safe: true,
seed: Math.floor(Math.random() * 100000),
style_type: "GENERAL",
}],
};
}// tests/ideogram.test.ts
import { describe, it, expect, vi } from "vitest";
import { IdeogramClient, IdeogramError } from "../src/ideogram/client";
import { mockGenerate } from "../src/ideogram/mock-server";
describe("IdeogramClient", () => {
it("should reject missing API key", () => {
expect(() => new IdeogramClient("")).toThrow("IDEOGRAM_API_KEY is required");
});
it("should construct generate request correctly", async () => {
const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValue(
new Response(JSON.stringify(mockGenerate("test")), { status: 200 })
);
const client = new IdeogramClient("test-key");
const result = await client.generate({ prompt: "test", model: "V_2" });
expect(fetchSpy).toHaveBeenCalledWith(
"https://api.ideogram.ai/generate",
expect.objectContaining({
method: "POST",
headers: expect.objectContaining({ "Api-Key": "test-key" }),
})
);
expect(result.data[0].prompt).toBe("test");
fetchSpy.mockRestore();
});
it("should throw IdeogramError on 401", async () => {
vi.spyOn(globalThis, "fetch").mockResolvedValue(
new Response("Unauthorized", { status: 401 })
);
const client = new IdeogramClient("bad-key");
await expect(client.generate({ prompt: "test" })).rejects.toThrow(IdeogramError);
});
});
describe("mockGenerate", () => {
it("should return valid response shape", () => {
const result = mockGenerate("hello world");
expect(result.data).toHaveLength(1);
expect(result.data[0].is_image_safe).toBe(true);
expect(result.data[0].seed).toBeGreaterThan(0);
});
});{
"scripts": {
"dev": "tsx watch src/index.ts",
"test": "vitest run",
"test:watch": "vitest --watch",
"generate": "tsx src/index.ts"
}
}| Error | Cause | Solution |
|---|---|---|
| Module not found | Missing dependency | Run npm install |
| Env not loaded | Missing .env.local | Copy from .env.example |
| Test timeout | Mocking not set up | Use mockGenerate in tests |
| Credits burned in tests | Using real API in CI | Mock fetch in test files |
See ideogram-sdk-patterns for production-ready code patterns.
4c47e33
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.