MAKEUGC PLATFORM API · DOCS V2
Shoppable ads
Generate product images and videos using category-specific creative formats. API paths use the spelling shopable.
Workflow
- Read /shopable/packs to discover categories, formats and defaults.
- Select an allowed format for the category and media type.
- Submit an image or video job and save data.id.
- Poll the matching image or video status endpoint.
Example IDs and media URLs are placeholders. Replace them with values from your account and accessible media files.
List creative packs #
/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 --fail-with-body --max-time 120 -X GET "https://app.makeugc.ai/api/platform/shopable/packs" \
-H "X-Api-Key: $MAKEUGC_API_KEY"
// 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);
# 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
{
"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 #
/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 --fail-with-body --max-time 120 -X GET "https://app.makeugc.ai/api/platform/shopable/packs/CATEGORY" \
-H "X-Api-Key: $MAKEUGC_API_KEY"
// 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);
# 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
{
"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 #
/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: |
format
string
Required
|
An allowed image/video format from the selected category pack.
Allowed: |
context
string
Required
|
Product details and creative direction.
Allowed: |
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: |
actors
object[]
Optional
|
Optional actors.
Allowed: |
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: |
actors[].dialogue
string | null
Optional
|
Actor dialogue.
Allowed: |
aspect_ratio
string
Optional
|
Output ratio. Read defaults from the packs endpoint.
Allowed: |
creative_seed
string | null
Optional
|
Creative variation identifier.
Allowed: |
creative_intensity
string | null
Optional
|
Creative direction strength.
Allowed: |
image_url
string
Required
|
Public product image URL; at most 2,000 characters. |
size
string
Optional
|
Image size preset.
Allowed: |
model
string
Optional
|
Image model ID. Read the default from packs.
Allowed: |
num_images
integer
Optional
|
Number of images.
Allowed: |
output_format
string
Optional
|
Image output format.
Allowed: |
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: |
Request example
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
}'
// 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);
# 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
{
"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 #
/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.
Parameters
| Parameter | Description |
|---|---|
id
string · query
Required
|
Job ID returned by the matching generation endpoint. |
Request example
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"
// 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);
# 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
{
"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 #
/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: |
format
string
Required
|
An allowed image/video format from the selected category pack.
Allowed: |
context
string
Required
|
Product details and creative direction.
Allowed: |
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: |
actors
object[]
Optional
|
Optional actors.
Allowed: |
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: |
actors[].dialogue
string | null
Optional
|
Actor dialogue.
Allowed: |
aspect_ratio
string
Optional
|
Output ratio. Read defaults from the packs endpoint.
Allowed: |
creative_seed
string | null
Optional
|
Creative variation identifier.
Allowed: |
creative_intensity
string | null
Optional
|
Creative direction strength.
Allowed: |
image_urls
string[]
Optional
|
Public product image URLs; at most 2,000 characters each.
Allowed: |
duration
string | null
Optional
|
Duration string; use the limits returned by packs.
Allowed: |
resolution
string
Optional
|
Output resolution.
Allowed: |
model
string
Optional
|
Video model.
Allowed: |
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: |
Request example
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"
}'
// 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);
# 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
{
"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 #
/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.
Parameters
| Parameter | Description |
|---|---|
id
string · query
Required
|
Job ID returned by the matching generation endpoint. |
Request example
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"
// 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);
# 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
{
"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.