API Reference
Complete reference for the Ddukddak REST API. Official SDKs for Node.js, TypeScript, and Python.
Base URL: https://api.ddukddak.studio/v1Auth: Bearer Token
Installation
npm install @ddukddak/nodeClient Initialization
const { Ddukddak } = require("@ddukddak/node");
const client = new Ddukddak("YOUR_API_KEY");
// Custom options
const client = new Ddukddak("YOUR_API_KEY", {
baseUrl: "https://api.ddukddak.studio/v1", // default
timeout: 30000, // milliseconds, default 30s
});Authentication
GET
/authVerify that your API key is valid. Returns a success message on authentication. Get your API key from Dashboard > Settings > API Keys.
const result = await client.auth.test();
console.log(result.message); // "Authenticated"Account
GET
/accountRetrieve account information including current API usage, quota, and plan details.
const account = await client.account.get();
console.log(`Usage: ${account.api_usage} / ${account.api_quota} credits`);Templates
List Templates
GET
/templatesReturns an array of templates (not wrapped in a data object).
| Parameter | Type | Required | Description |
|---|---|---|---|
| page | integer | No | Page number (default: 1) |
| limit | integer | No | Items per page, max 100 (default: 25) |
Response fields
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | Template unique identifier |
| name | string | Yes | Template display name |
| slug | string | Yes | URL-friendly identifier |
| canvas_width | integer | Yes | Canvas width in pixels |
| canvas_height | integer | Yes | Canvas height in pixels |
| background_color | string | Yes | Hex color (e.g. #FFFFFF) |
| created_at | timestamp | Yes | Creation date |
| updated_at | timestamp | Yes | Last update date |
// Returns an array directly (not wrapped in { data: [...] })
const templates = await client.templates.list({ page: 1, limit: 10 });
for (const t of templates) {
console.log(`- ${t.id} (${t.slug}): ${t.name}`);
console.log(` Size: ${t.canvas_width}x${t.canvas_height}`);
}Get Template Detail
GET
/templates/{id}Retrieve template details including available_properties. Requires a UUID (not slug).
Response fields
| Parameter | Type | Required | Description |
|---|---|---|---|
| uid | uuid | Yes | Template ID |
| name | string | Yes | Template name |
| slug | string | Yes | URL slug |
| width | integer | Yes | Canvas width |
| height | integer | Yes | Canvas height |
| available_properties | array | Yes | Customizable layers (name, type, defaults) |
// Requires UUID (not slug)
const template = await client.templates.get(templates[0].id);
console.log("Name:", template.name);
console.log("Slug:", template.slug);
console.log("Size:", template.width, "x", template.height);
console.log("Properties:");
for (const prop of template.available_properties) {
console.log(` - ${prop.name}: ${prop.type}`);
}Images
Create Image
POST
/images| Parameter | Type | Required | Description |
|---|---|---|---|
| template | string | Yes | Template slug or UUID |
| properties | array | No | List of property objects (name, text, image_url, color) |
| transparent | boolean | No | Transparent background (default: false) |
| webhook_url | string | No | URL to receive completion callback |
// Async — returns immediately with status "pending"
const image = await client.images.create({
template: "product-card", // slug or UUID
properties: [
{ name: "title", text: "My Awesome Product!" },
{ name: "background", image_url: "https://example.com/bg.jpg" },
{ name: "price", text: "$29.99", color: "#FF6B6B" },
],
transparent: false, // optional, default false
webhook_url: "https://...", // optional
});
console.log(image.uid); // "img_abc123..."
console.log(image.status); // "pending"Create and Wait
Convenience method that creates an image and polls until completion. Not a separate API endpoint — handled by the SDK.
// Polls until completed or failed
const image = await client.images.createAndWait(
{
template: "product-card",
properties: [
{ name: "title", text: "Hello World" },
],
},
3000, // pollInterval (ms), default 3000
300000, // timeout (ms), default 300000
);
console.log(image.image_url);List / Get Images
GET
/imagesGET
/images/{uid}// List generated images
const images = await client.images.list({ page: 1, limit: 10 });
for (const img of images) {
console.log(`[${img.status}] ${img.uid}`);
}
// Get a specific image by UID
const detail = await client.images.get("img_abc123...");
console.log(detail.image_url);Videos
Create Video
POST
/videosAutomate plan+| Parameter | Type | Required | Description |
|---|---|---|---|
| template | string | Yes | Template slug or UUID |
| input_media_url | string | Yes | Input video/media URL |
| properties | array | No | Property objects to inject |
| audio_url | string | No | Background audio URL |
| webhook_url | string | No | Completion callback URL |
// Requires Automate plan or higher
const video = await client.videos.create({
template: "story-promo", // slug or UUID
input_media_url: "https://example.com/clip.mp4",
properties: [
{ name: "title", text: "Spring Sale 2026" },
{ name: "subtitle", text: "Up to 50% off" },
],
audio_url: "https://example.com/bgm.mp3", // optional
webhook_url: "https://...", // optional
});
console.log(video.uid); // track with this ID
console.log(video.status); // "pending"Create and Wait
const video = await client.videos.createAndWait(
{
template: "story-promo",
input_media_url: "https://example.com/clip.mp4",
properties: [{ name: "title", text: "Spring Sale" }],
},
5000, // pollInterval (ms), default 5000
600000, // timeout (ms), default 600000
);
console.log(video.video_url);AI Images
Create AI Image
POST
/ai/imagesScale plan+| Parameter | Type | Required | Description |
|---|---|---|---|
| prompt | string | Yes | Text description of the image |
| model | string | No | AI model (default: gemini-2.5-flash-image) |
| aspect_ratio | string | No | Aspect ratio (default: 1:1) |
| image_size | string | No | Size: 512, 1K, 2K, 4K, HD (default: 1K) |
| webhook_url | string | No | Completion callback URL |
Available models
| Model ID | Name | Sizes | Ratios |
|---|---|---|---|
| gemini-2.5-flash-image | Nano Banana | 1K | 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9 |
| gemini-3.1-flash-image-preview | Nano Banana 2 | 512, 1K, 2K, 4K | All 14 ratios |
| gemini-3-pro-image-preview | Nano Banana Pro | 1K, 2K, 4K | 10 common ratios |
| image-01 | Hailuo Image | HD only | 1:1, 16:9, 4:3, 3:2, 2:3, 3:4, 9:16, 21:9 |
// Requires Scale plan or higher
// Increase timeout for AI generation
const client = new Ddukddak("YOUR_API_KEY", { timeout: 120000 });
// Gemini model
const aiImage = await client.aiImages.createAndWait({
prompt: "A minimalist product photo of a white sneaker",
model: "gemini-2.5-flash-image",
aspect_ratio: "1:1",
image_size: "1K",
});
console.log(aiImage.image_url);
// Hailuo Image model (MiniMax)
const hailuoImage = await client.aiImages.createAndWait({
prompt: "Cute bear mascot holding a camera",
model: "image-01",
aspect_ratio: "16:9",
image_size: "HD", // image-01 only supports "HD"
});
console.log(hailuoImage.image_url);AI Videos
Create AI Video
POST
/ai/videosScale plan+| Parameter | Type | Required | Description |
|---|---|---|---|
| prompt | string | Yes | Text description of the video |
| model | string | No | AI model (default: MiniMax-Hailuo-2.3) |
| aspect_ratio | string | No | Aspect ratio (default: 16:9) |
| resolution | string | No | Resolution (default: 768p) |
| duration | string | No | Duration string: 4s, 6s, 8s, 10s (default: 6s) |
| webhook_url | string | No | Completion callback URL |
Available models
| Model ID | Name | Ratios | Resolutions | Durations |
|---|---|---|---|---|
| MiniMax-Hailuo-2.3 | Hailuo 2.3 | 16:9 | 768p, 1080p | 6s, 10s (1080p: 6s only) |
| veo-3.1-fast-generate-preview | Veo 3.1 Fast | 16:9, 9:16 | 720p, 1080p | 4s, 6s, 8s |
| veo-3.1-generate-preview | Veo 3.1 | 16:9, 9:16 | 720p, 1080p, 4K | 4s, 6s, 8s |
| veo-3.0-fast-generate-preview | Veo 3 Fast | 16:9 | 720p, 1080p | 4s, 6s, 8s |
// Requires Scale plan or higher
const client = new Ddukddak("YOUR_API_KEY", { timeout: 300000 });
// MiniMax Hailuo model
const video = await client.aiVideos.createAndWait(
{
prompt: "A white sneaker rotating 360 degrees",
model: "MiniMax-Hailuo-2.3",
aspect_ratio: "16:9", // MiniMax: "16:9" only
resolution: "768p", // "768p" or "1080p"
duration: "6s", // "6s" or "10s"
},
5000, 600000,
);
console.log(video.video_url);
// Google Veo 3.1 Fast model
const veoVideo = await client.aiVideos.createAndWait(
{
prompt: "Barista making latte art, close-up",
model: "veo-3.1-fast-generate-preview",
aspect_ratio: "9:16", // Veo supports "9:16"
resolution: "1080p", // "720p" or "1080p"
duration: "6s", // "4s", "6s", "8s"
},
5000, 600000,
);
console.log(veoVideo.video_url);Error Handling
| Status | Exception | Description |
|---|---|---|
| 400 | ValidationError | Invalid request parameters |
| 401 | AuthenticationError | Invalid or missing API key |
| 402 | QuotaExceededError | Monthly credit limit reached |
| 403 | PlanRestrictedError | Feature not available on current plan |
| 404 | NotFoundError | Resource (template, image, video) not found |
| 429 | RateLimitError | Too many requests — retry after backoff |
const {
Ddukddak,
AuthenticationError,
ValidationError,
QuotaExceededError,
PlanRestrictedError,
RateLimitError,
NotFoundError,
DdukddakError,
} = require("@ddukddak/node");
try {
const image = await client.images.create({ template: "..." });
} catch (error) {
if (error instanceof AuthenticationError)
console.log("Invalid API key");
else if (error instanceof QuotaExceededError)
console.log("Monthly credit limit reached");
else if (error instanceof PlanRestrictedError)
console.log("Feature not available on your plan");
else if (error instanceof RateLimitError)
console.log("Too many requests, retry later");
else if (error instanceof NotFoundError)
console.log("Template not found");
else if (error instanceof ValidationError)
console.log("Invalid parameters:", error.message);
else if (error instanceof DdukddakError)
console.log("Error:", error.message);
}Plan Limits
| Feature | Free Trial | Automate $49/mo | Scale $149/mo | Enterprise $299/mo |
|---|---|---|---|---|
| API Credits | 30 | 1,000 | 10,000 | 50,000 |
| Image Generation | Yes | Yes | Yes | Yes |
| Video Generation | — | Yes | Yes | Yes |
| AI Image Generation | — | — | Yes | Yes |
| AI Video Generation | — | — | Yes | Yes |
| Bandwidth | — | 10 GB | 50 GB | 100 GB |
| Priority Support | — | — | Yes | Yes |