Skip to content
Developers
API docs / Features

MAKEUGC PLATFORM API · DOCS V2

Shoppable ads

Generate product images and videos using category-specific creative formats. API paths use the spelling shopable.

Workflow

  1. Read /shopable/packs to discover categories, formats and defaults.
  2. Select an allowed format for the category and media type.
  3. Submit an image or video job and save data.id.
  4. Poll the matching image or video status endpoint.
Use the public /shopable/images/status or /shopable/videos/status endpoint. An upstream poll_path in the generation response is not a replacement for these paths.
The image route accepts webhook_url and webhook_secret. The video route does not accept webhook fields; use polling.

Example IDs and media URLs are placeholders. Replace them with values from your account and accessible media files.

List creative packs #

GET /shopable/packs

Returns defaults, supported formats, model choices and categories. The example shows the response structure; use values from your actual response.

Parameters

No request parameters.

Request example

cURL
curl --fail-with-body --max-time 120 -X GET "https://app.makeugc.ai/api/platform/shopable/packs" \
  -H "X-Api-Key: $MAKEUGC_API_KEY"
JavaScript
// Run on your server with Node.js 20+.
const apiKey = process.env.MAKEUGC_API_KEY;
if (!apiKey) throw new Error("Set MAKEUGC_API_KEY first");

const response = await fetch("https://app.makeugc.ai/api/platform/shopable/packs", {
  method: "GET",
  headers: {
    "X-Api-Key": apiKey,
  },
  signal: AbortSignal.timeout(120000),
});
const text = await response.text();
if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${text} (request ${response.headers.get("x-request-id")})`);
}
const result = JSON.parse(text);
console.log(result);
Python
# Install the requests package before running.
import os
import requests

response = requests.get(
    "https://app.makeugc.ai/api/platform/shopable/packs",
    headers={"X-Api-Key": os.environ["MAKEUGC_API_KEY"]},
    timeout=120,
)
if not response.ok:
    raise RuntimeError(f"HTTP {response.status_code}: {response.text} "
                       f"(request {response.headers.get('x-request-id')})")
print(response.json())

200 response example

JSON response
{
  "status": true,
  "message": "Shopable packs",
  "data": {
    "default_category": "CATEGORY_ID",
    "default_image_format": "IMAGE_FORMAT",
    "default_video_format": "VIDEO_FORMAT",
    "default_aspect_ratio": "9:16",
    "default_video_duration": "10",
    "video_duration_min": 4,
    "video_duration_max": 15,
    "default_image_model": "MODEL_ID",
    "default_video_model": "seedance-2.0-fast",
    "video_models": [
      "seedance-2.0",
      "seedance-2.0-fast"
    ],
    "image_formats": [
      "IMAGE_FORMAT"
    ],
    "video_formats": [
      "VIDEO_FORMAT"
    ],
    "categories": [
      {
        "id": "CATEGORY_ID",
        "display_name": "Example category",
        "recommended_image_formats": [
          "IMAGE_FORMAT"
        ],
        "recommended_video_formats": [
          "VIDEO_FORMAT"
        ],
        "allowed_image_formats": [
          "IMAGE_FORMAT"
        ],
        "allowed_video_formats": [
          "VIDEO_FORMAT"
        ]
      }
    ]
  }
}

All requests require X-Api-Key. See errors & retries for unsuccessful responses.

Get a category pack #

GET /shopable/packs/{category}

URL-encode the category ID returned by the pack list.

Parameters

Parameter Description
category
string · path
Required
Category ID from /shopable/packs.

Request example

cURL
curl --fail-with-body --max-time 120 -X GET "https://app.makeugc.ai/api/platform/shopable/packs/CATEGORY" \
  -H "X-Api-Key: $MAKEUGC_API_KEY"
JavaScript
// Run on your server with Node.js 20+.
const apiKey = process.env.MAKEUGC_API_KEY;
if (!apiKey) throw new Error("Set MAKEUGC_API_KEY first");

const response = await fetch("https://app.makeugc.ai/api/platform/shopable/packs/CATEGORY", {
  method: "GET",
  headers: {
    "X-Api-Key": apiKey,
  },
  signal: AbortSignal.timeout(120000),
});
const text = await response.text();
if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${text} (request ${response.headers.get("x-request-id")})`);
}
const result = JSON.parse(text);
console.log(result);
Python
# Install the requests package before running.
import os
import requests

response = requests.get(
    "https://app.makeugc.ai/api/platform/shopable/packs/CATEGORY",
    headers={"X-Api-Key": os.environ["MAKEUGC_API_KEY"]},
    timeout=120,
)
if not response.ok:
    raise RuntimeError(f"HTTP {response.status_code}: {response.text} "
                       f"(request {response.headers.get('x-request-id')})")
print(response.json())

200 response example

JSON response
{
  "status": true,
  "message": "Shopable pack",
  "data": {
    "id": "CATEGORY_ID",
    "display_name": "Example category",
    "recommended_image_formats": [
      "IMAGE_FORMAT"
    ],
    "recommended_video_formats": [
      "VIDEO_FORMAT"
    ],
    "allowed_image_formats": [
      "IMAGE_FORMAT"
    ],
    "allowed_video_formats": [
      "VIDEO_FORMAT"
    ]
  }
}

All requests require X-Api-Key. See errors & retries for unsuccessful responses.

Generate a product image #

POST /shopable/images

Creates an asynchronous image job. Read data.id and any returned warnings or credits_used.

Request body

Parameter Description
category
string
Required
Category ID from /shopable/packs.

Allowed: 1–100 characters

format
string
Required
An allowed image/video format from the selected category pack.

Allowed: 1–100 characters

context
string
Required
Product details and creative direction.

Allowed: 1–4,000 characters

project_id
string | null
Optional
Existing project owned by your account. Takes precedence over project_name.
project_name
string | null
Optional
Find or create a store project by name.

Allowed: 1–256 characters

actors
object[]
Optional
Optional actors.

Allowed: Up to 4 actors

actors[].image_url
string
Required
Public image URL for each supplied actor; at most 2,000 characters.
actors[].audio_url
string | null
Optional
Public actor audio URL; at most 2,000 characters.
actors[].name
string | null
Optional
Actor name.

Allowed: Up to 100 characters

actors[].dialogue
string | null
Optional
Actor dialogue.

Allowed: Up to 500 characters

aspect_ratio
string
Optional
Output ratio. Read defaults from the packs endpoint.

Allowed: Up to 20 characters

creative_seed
string | null
Optional
Creative variation identifier.

Allowed: Up to 64 characters

creative_intensity
string | null
Optional
Creative direction strength.

Allowed: elegant | bold | surreal

image_url
string
Required
Public product image URL; at most 2,000 characters.
size
string
Optional
Image size preset.

Allowed: Up to 32 characters

model
string
Optional
Image model ID. Read the default from packs.

Allowed: 1–100 characters

num_images
integer
Optional
Number of images.

Allowed: 1–4

output_format
string
Optional
Image output format.

Allowed: png | jpeg

watermark
boolean
Optional
Whether to add an image watermark.
webhook_url
string
Optional
Public HTTP(S) callback URL. Use status polling as a fallback.
webhook_secret
string | null
Optional
Optional callback secret. Confirm callback verification details for your integration; no universal signature scheme is specified here.

Allowed: 8–256 characters

Request example

cURL
curl --fail-with-body --max-time 120 -X POST "https://app.makeugc.ai/api/platform/shopable/images" \
  -H "X-Api-Key: $MAKEUGC_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
  "category": "CATEGORY_ID",
  "format": "IMAGE_FORMAT",
  "context": "A ceramic cup for a calm morning routine.",
  "image_url": "https://your-cdn.example/product.jpg",
  "num_images": 1
}'
JavaScript
// Run on your server with Node.js 20+.
const apiKey = process.env.MAKEUGC_API_KEY;
if (!apiKey) throw new Error("Set MAKEUGC_API_KEY first");

const response = await fetch("https://app.makeugc.ai/api/platform/shopable/images", {
  method: "POST",
  headers: {
    "X-Api-Key": apiKey,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "category": "CATEGORY_ID",
  "format": "IMAGE_FORMAT",
  "context": "A ceramic cup for a calm morning routine.",
  "image_url": "https://your-cdn.example/product.jpg",
  "num_images": 1
}),
  signal: AbortSignal.timeout(120000),
});
const text = await response.text();
if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${text} (request ${response.headers.get("x-request-id")})`);
}
const result = JSON.parse(text);
console.log(result);
Python
# Install the requests package before running.
import os
import requests

payload = {
    "category": "CATEGORY_ID",
    "format": "IMAGE_FORMAT",
    "context": "A ceramic cup for a calm morning routine.",
    "image_url": "https://your-cdn.example/product.jpg",
    "num_images": 1
}

response = requests.post(
    "https://app.makeugc.ai/api/platform/shopable/images",
    headers={"X-Api-Key": os.environ["MAKEUGC_API_KEY"]},
    json=payload,
    timeout=120,
)
if not response.ok:
    raise RuntimeError(f"HTTP {response.status_code}: {response.text} "
                       f"(request {response.headers.get('x-request-id')})")
print(response.json())

201 response example

JSON response
{
  "status": true,
  "message": "Image generation started",
  "data": {
    "id": "image_123",
    "status": 0,
    "category": "CATEGORY_ID",
    "format": "IMAGE_FORMAT",
    "poll_path": "/shopable/images/status?id=image_123"
  }
}

All requests require X-Api-Key. See errors & retries for unsuccessful responses.

Get image status #

GET /shopable/images/status

Poll every 5–10 seconds. Stop on failed, or completed with a non-empty URL. The outer status boolean describes the API request; data.status describes the job.

While processing, data.status is processing and url is absent. On failure, data.status is failed; a reason may be included. Save output files if you need permanent access.

Parameters

Parameter Description
id
string · query
Required
Job ID returned by the matching generation endpoint.

Request example

cURL
curl --fail-with-body --max-time 120 -X GET "https://app.makeugc.ai/api/platform/shopable/images/status?id=ID" \
  -H "X-Api-Key: $MAKEUGC_API_KEY"
JavaScript
// Run on your server with Node.js 20+.
const apiKey = process.env.MAKEUGC_API_KEY;
if (!apiKey) throw new Error("Set MAKEUGC_API_KEY first");

const response = await fetch("https://app.makeugc.ai/api/platform/shopable/images/status?id=ID", {
  method: "GET",
  headers: {
    "X-Api-Key": apiKey,
  },
  signal: AbortSignal.timeout(120000),
});
const text = await response.text();
if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${text} (request ${response.headers.get("x-request-id")})`);
}
const result = JSON.parse(text);
console.log(result);
Python
# Install the requests package before running.
import os
import requests

response = requests.get(
    "https://app.makeugc.ai/api/platform/shopable/images/status?id=ID",
    headers={"X-Api-Key": os.environ["MAKEUGC_API_KEY"]},
    timeout=120,
)
if not response.ok:
    raise RuntimeError(f"HTTP {response.status_code}: {response.text} "
                       f"(request {response.headers.get('x-request-id')})")
print(response.json())

200 response example

JSON response
{
  "status": true,
  "message": "Image is completed",
  "data": {
    "raw_status": 1,
    "status": "completed",
    "url": "https://your-cdn.example/result.png"
  }
}

All requests require X-Api-Key. See errors & retries for unsuccessful responses.

Generate a product video #

POST /shopable/videos

Creates an asynchronous video job. Category and format values must come from the live pack list.

Request body

Parameter Description
category
string
Required
Category ID from /shopable/packs.

Allowed: 1–100 characters

format
string
Required
An allowed image/video format from the selected category pack.

Allowed: 1–100 characters

context
string
Required
Product details and creative direction.

Allowed: 1–4,000 characters

project_id
string | null
Optional
Existing project owned by your account. Takes precedence over project_name.
project_name
string | null
Optional
Find or create a store project by name.

Allowed: 1–256 characters

actors
object[]
Optional
Optional actors.

Allowed: Up to 4 actors

actors[].image_url
string
Required
Public image URL for each supplied actor; at most 2,000 characters.
actors[].audio_url
string | null
Optional
Public actor audio URL; at most 2,000 characters.
actors[].name
string | null
Optional
Actor name.

Allowed: Up to 100 characters

actors[].dialogue
string | null
Optional
Actor dialogue.

Allowed: Up to 500 characters

aspect_ratio
string
Optional
Output ratio. Read defaults from the packs endpoint.

Allowed: Up to 20 characters

creative_seed
string | null
Optional
Creative variation identifier.

Allowed: Up to 64 characters

creative_intensity
string | null
Optional
Creative direction strength.

Allowed: elegant | bold | surreal

image_urls
string[]
Optional
Public product image URLs; at most 2,000 characters each.

Allowed: Up to 4 images

duration
string | null
Optional
Duration string; use the limits returned by packs.

Allowed: Up to 8 characters

resolution
string
Optional
Output resolution.

Allowed: Up to 20 characters

model
string
Optional
Video model.

Allowed: seedance-2.0 | seedance-2.0-fast

check_human
boolean
Optional
Enable human-content checking.
add_watermark
boolean
Optional
Add a video watermark.
source_asset_id
string | null
Optional
Optional source image asset ID.

Allowed: Up to 64 characters

Request example

cURL
curl --fail-with-body --max-time 120 -X POST "https://app.makeugc.ai/api/platform/shopable/videos" \
  -H "X-Api-Key: $MAKEUGC_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{
  "category": "CATEGORY_ID",
  "format": "VIDEO_FORMAT",
  "context": "A warm, natural product showcase.",
  "image_urls": [
    "https://your-cdn.example/product.jpg"
  ],
  "model": "seedance-2.0-fast",
  "duration": "10"
}'
JavaScript
// Run on your server with Node.js 20+.
const apiKey = process.env.MAKEUGC_API_KEY;
if (!apiKey) throw new Error("Set MAKEUGC_API_KEY first");

const response = await fetch("https://app.makeugc.ai/api/platform/shopable/videos", {
  method: "POST",
  headers: {
    "X-Api-Key": apiKey,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "category": "CATEGORY_ID",
  "format": "VIDEO_FORMAT",
  "context": "A warm, natural product showcase.",
  "image_urls": [
    "https://your-cdn.example/product.jpg"
  ],
  "model": "seedance-2.0-fast",
  "duration": "10"
}),
  signal: AbortSignal.timeout(120000),
});
const text = await response.text();
if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${text} (request ${response.headers.get("x-request-id")})`);
}
const result = JSON.parse(text);
console.log(result);
Python
# Install the requests package before running.
import os
import requests

payload = {
    "category": "CATEGORY_ID",
    "format": "VIDEO_FORMAT",
    "context": "A warm, natural product showcase.",
    "image_urls": ["https://your-cdn.example/product.jpg"],
    "model": "seedance-2.0-fast",
    "duration": "10"
}

response = requests.post(
    "https://app.makeugc.ai/api/platform/shopable/videos",
    headers={"X-Api-Key": os.environ["MAKEUGC_API_KEY"]},
    json=payload,
    timeout=120,
)
if not response.ok:
    raise RuntimeError(f"HTTP {response.status_code}: {response.text} "
                       f"(request {response.headers.get('x-request-id')})")
print(response.json())

201 response example

JSON response
{
  "status": true,
  "message": "Video generation started",
  "data": {
    "id": "video_123",
    "status": "0",
    "category": "CATEGORY_ID",
    "format": "VIDEO_FORMAT",
    "poll_path": "/shopable/videos/status?id=video_123"
  }
}

All requests require X-Api-Key. See errors & retries for unsuccessful responses.

Get video status #

GET /shopable/videos/status

Poll every 5–10 seconds. Stop on failed, or completed with a non-empty URL. The outer status boolean describes the API request; data.status describes the job.

While processing, data.status is processing and url is absent. On failure, data.status is failed; a reason may be included. Save output files if you need permanent access.

Parameters

Parameter Description
id
string · query
Required
Job ID returned by the matching generation endpoint.

Request example

cURL
curl --fail-with-body --max-time 120 -X GET "https://app.makeugc.ai/api/platform/shopable/videos/status?id=ID" \
  -H "X-Api-Key: $MAKEUGC_API_KEY"
JavaScript
// Run on your server with Node.js 20+.
const apiKey = process.env.MAKEUGC_API_KEY;
if (!apiKey) throw new Error("Set MAKEUGC_API_KEY first");

const response = await fetch("https://app.makeugc.ai/api/platform/shopable/videos/status?id=ID", {
  method: "GET",
  headers: {
    "X-Api-Key": apiKey,
  },
  signal: AbortSignal.timeout(120000),
});
const text = await response.text();
if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${text} (request ${response.headers.get("x-request-id")})`);
}
const result = JSON.parse(text);
console.log(result);
Python
# Install the requests package before running.
import os
import requests

response = requests.get(
    "https://app.makeugc.ai/api/platform/shopable/videos/status?id=ID",
    headers={"X-Api-Key": os.environ["MAKEUGC_API_KEY"]},
    timeout=120,
)
if not response.ok:
    raise RuntimeError(f"HTTP {response.status_code}: {response.text} "
                       f"(request {response.headers.get('x-request-id')})")
print(response.json())

200 response example

JSON response
{
  "status": true,
  "message": "Video is completed",
  "data": {
    "raw_status": "1",
    "status": "completed",
    "url": "https://your-cdn.example/result.mp4"
  }
}

All requests require X-Api-Key. See errors & retries for unsuccessful responses.