We can't find the internet
Attempting to reconnect
Reconnecting...
Please wait a moment
Fetch AI-generated product scenes and catalog data via REST. Use
/api/v1/products
to drop SceneSKU into any ecommerce demo as a plug-in product API, or use the canonical
/api/v1/scene-packs
path — both are identical.
Interactive Explorer
Browse all endpoints, try live requests, and inspect response schemas with the Swagger UI.
Fast-track your integration
Skip the setup and explore a production-ready Next.js 16 GitHub Boilerplate & Live Demo that shows exactly how to fetch and render scene packs in a real headless storefront. Clone it to bypass the data vacuum entirely.
Fetch your first scene pack in three steps:
# List active categories (no auth needed)
curl https://scenesku.com/api/v1/categories
# List products — /api/v1/products and /api/v1/scene-packs are identical
curl https://scenesku.com/api/v1/products \
-H "Authorization: Bearer $SCENESKU_API_KEY"
# Get a specific product/pack by ID
curl https://scenesku.com/api/v1/products/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer $SCENESKU_API_KEY"
Every API request must include your API key as a bearer token in the
Authorization
header. Create and manage keys in Dashboard → API Keys.
Authorization: Bearer YOUR_SCENESKU_API_KEY
401 Unauthorized. Keep your key secret and rotate it from the dashboard if compromised.
/api/v1/categories
Returns all active categories sorted by display order then name. Use these slugs with the
category
filter on the scene packs endpoint or browse packs directly via the category route below. No authentication required.
{
"data": [
{
"id": "a1b2c3d4-...",
"name": "Electronics",
"slug": "electronics",
"description": "Consumer electronics and gadgets",
"sort_order": 0
},
{
"id": "e5f6g7h8-...",
"name": "Fashion & Apparel",
"slug": "fashion-apparel",
"description": null,
"sort_order": 1
}
]
}
/api/v1/categories/:slug/scene-packs
Returns published scene packs tagged with the given category slug. Pagination and plan behaviour is identical to the List Scene Packs endpoint.
slug
string
required
Category slug from the
List Categories
endpoint (e.g. electronics). Returns
404
if the slug is not found or inactive.
page
integer
default: 1
Page number (Pro plan only, minimum 1).
per_page
integer
default: 20
Results per page, maximum 100 (Pro plan only).
curl https://scenesku.com/api/v1/categories/electronics/scene-packs \
-H "Authorization: Bearer $SCENESKU_API_KEY"
Response shape is identical to
List Scene Packs
— a data
array of scene packs with a meta
object.
/api/v1/scene-packs
/api/v1/products
alias
Returns public, published scene packs including images and product data. Both paths are identical — use
/api/v1/products
when integrating with ecommerce frameworks that expect a standard products endpoint. Behaviour varies by plan:
Returns up to the plan's download limit. No pagination.
meta.limit
shows the cap.
Returns all packs with cursor-style offset pagination via
page
and per_page.
page
integer
default: 1
Page number (Pro plan only, minimum 1).
per_page
integer
default: 20
Results per page, maximum 100 (Pro plan only).
category
string
default: —
Filter by category slug (e.g. apparel). Use GET /api/v1/categories to list available slugs.
custom_category
string
default: —
Filter by custom category text (case-insensitive substring match).
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"visibility": "public",
"images": [
{ "index": 0, "image_url": "https://..." },
{ "index": 1, "image_url": "https://..." }
],
"product_data": {
"product_title": "Matte Black Travel Tumbler",
"short_description": "Sleek 20oz insulated tumbler for on-the-go hydration.",
"long_description": "...",
"bullet_points": ["BPA-free", "Double-wall insulation", "Fits most cup holders"],
"price": "34.99",
"categories": ["Kitchen", "Travel"],
"tags": ["tumbler", "insulated", "travel"],
"collections": ["Best Sellers"],
"options": { "size": ["20oz", "32oz"], "color": ["Matte Black", "Navy"] },
"attributes": { "material": "Stainless steel", "capacity": "20oz" },
"language": "en",
"status": "active"
}
}
],
"meta": {
"plan": "pro",
"page": 1,
"per_page": 20,
"total": 48,
"total_pages": 3
}
}
/api/v1/scene-packs/:id
/api/v1/products/:id
alias
Returns a single public, published scene pack by its UUID, including all succeeded images and product data. Returns
404
if the pack does not exist, is private, or is unpublished.
id
uuid
required
The scene pack UUID.
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"visibility": "public",
"images": [
{ "index": 0, "image_url": "https://..." },
{ "index": 1, "image_url": "https://..." },
{ "index": 2, "image_url": "https://..." }
],
"product_data": {
"product_title": "Matte Black Travel Tumbler",
"short_description": "...",
"long_description": "...",
"bullet_points": ["BPA-free", "Double-wall insulation"],
"price": "34.99",
"categories": ["Kitchen"],
"tags": ["tumbler", "travel"],
"collections": [],
"options": null,
"attributes": null,
"language": "en",
"status": "active"
}
}
}
SceneSKU Scene Packs are commonly used to seed ecommerce store demos and mockups with realistic product data and lifestyle images. To make integration more intuitive, every scene-packs endpoint is also available under /api/v1/products.
If your storefront or demo framework expects a
/products
endpoint, point it directly at SceneSKU — no proxy or adapter needed.
# Drop-in product catalog for your store demo
curl "https://scenesku.com/api/v1/products?category=apparel&per_page=20" \
-H "Authorization: Bearer $SCENESKU_API_KEY"
# Fetch a single product by ID
curl "https://scenesku.com/api/v1/products/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer $SCENESKU_API_KEY"
id
uuid
Unique identifier for the scene pack.
visibility
string
Always "public" for API-accessible packs.
images
array
List of succeeded images, sorted by index. Each item has index (integer) and image_url (string).
product_data
object | null
Product catalog data. Null if no product data was generated for this pack.
product_title
string | null
Product name, suitable for a store listing title.
short_description
string | null
One-line or brief product description.
long_description
string | null
Full product description, may contain multiple paragraphs.
bullet_points
string[]
List of feature/benefit bullet points.
price
string | null
Decimal price as a string (e.g. "34.99"). Null if not generated.
categories
string[]
Product categories (e.g. ["Kitchen", "Travel"]).
tags
string[]
SEO and search tags.
collections
string[]
Store collections this product belongs to.
options
object | null
Product variants (e.g. {"color": ["Black", "White"], "size": ["S", "M", "L"]}).
attributes
object | null
Product attributes (e.g. {"material": "Stainless steel"}).
language
string | null
ISO 639-1 language code of the generated content (e.g. "en").
status
string | null
Lifecycle status of the product data (e.g. "active").
# List active categories (no auth required)
curl https://scenesku.com/api/v1/categories
# Browse packs in a specific category
curl https://scenesku.com/api/v1/categories/electronics/scene-packs \
-H "Authorization: Bearer $SCENESKU_API_KEY"
# List products (/api/v1/products and /api/v1/scene-packs are identical)
curl https://scenesku.com/api/v1/products \
-H "Authorization: Bearer $SCENESKU_API_KEY"
# Filter by category + paginate (Pro plan)
curl "https://scenesku.com/api/v1/products?category=apparel&page=2&per_page=10" \
-H "Authorization: Bearer $SCENESKU_API_KEY"
# Get a specific product by ID
curl "https://scenesku.com/api/v1/products/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer $SCENESKU_API_KEY"
Create a dedicated API key for each app or service that calls the API. If a key leaks, rotate only that one without disrupting other integrations.
On the Pro plan, always paginate through results using page and per_page. Don't assume all packs fit in a single response.
Images are already filtered to succeeded status in the API response. All image_url values are ready to use — no additional status check needed.
Scene pack content changes infrequently. Cache the list response in your app rather than fetching on every request to reduce latency.
The product_data block is designed to seed ecommerce platforms directly. Map title, categories, tags, and options to your platform's schema.
Some packs may have null product_data. Always check before accessing nested fields to avoid runtime errors.
Convert PNG and JPEG images to WebP programmatically. Send files as multipart/form-data, get back base64-encoded WebP binaries in the same response. Authentication uses the same Bearer token as all other API endpoints.
/api/v1/convert
images[]
file
required
One or more PNG or JPEG files. Send multiple as repeated form fields.
quality
integer
default: 80
WebP output quality, 1–100. Higher = better fidelity, larger file.
{
"data": {
"converted": 2,
"failed": 0,
"files": [
{ "filename": "product.webp", "data": "<base64-encoded WebP binary>" },
{ "filename": "banner.webp", "data": "<base64-encoded WebP binary>" }
],
"failures": []
}
}
data.converted
integer
Number of files successfully converted.
data.failed
integer
Number of files that failed to convert.
data.files[].filename
string
Output filename — extension changed to .webp.
data.files[].data
string
Base64-encoded WebP binary. Decode and save directly.
data.failures
array
Error details for each failed file: filename and error message.
| Status | Meaning |
|---|---|
400
|
Missing or invalid field (wrong type, no images) |
401
|
Missing or invalid API key |
413
|
File exceeds 10 MB size limit |
422
|
All conversions failed |
429
|
Rate limit exceeded |
# Convert a single image
curl -X POST https://scenesku.com/api/v1/convert \
-H "Authorization: Bearer $SCENESKU_API_KEY" \
-F "images[][email protected]" \
| jq -r '.data.files[0].data' | base64 -d > product.webp
# Convert multiple images with custom quality
curl -X POST https://scenesku.com/api/v1/convert \
-H "Authorization: Bearer $SCENESKU_API_KEY" \
-F "images[][email protected]" \
-F "images[][email protected]" \
-F "quality=90"
// Node 18+ — no npm packages needed
import { readFileSync, writeFileSync } from "node:fs";
import { basename, extname } from "node:path";
async function convertToWebP(apiKey: string, files: string[], quality = 80) {
const form = new FormData();
form.append("quality", String(quality));
for (const filePath of files) {
const ext = extname(filePath).toLowerCase();
const mime = ext === ".png" ? "image/png" : "image/jpeg";
form.append("images[]", new Blob([readFileSync(filePath)], { type: mime }), basename(filePath));
}
const resp = await fetch("https://scenesku.com/api/v1/convert", {
method: "POST",
headers: { Authorization: `Bearer ${apiKey}` },
body: form,
});
if (!resp.ok) throw new Error(`API error ${resp.status}`);
const { data } = await resp.json();
for (const file of data.files) {
const buf = Buffer.from(file.data, "base64");
writeFileSync(file.filename, buf);
console.log(`Saved ${file.filename} (${buf.length.toLocaleString()} bytes)`);
}
}
await convertToWebP(process.env.SCENESKU_API_KEY!, ["product.png", "banner.jpg"], 85);
import base64, os, requests
from pathlib import Path
def convert_to_webp(api_key: str, files: list[str], quality: int = 80):
file_handles, multipart = [], []
try:
for path in files:
p = Path(path)
mime = "image/png" if p.suffix.lower() == ".png" else "image/jpeg"
f = open(p, "rb")
file_handles.append(f)
multipart.append(("images[]", (p.name, f, mime)))
resp = requests.post(
"https://scenesku.com/api/v1/convert",
headers={"Authorization": f"Bearer {api_key}"},
files=multipart,
data={"quality": quality},
)
finally:
for f in file_handles:
f.close()
resp.raise_for_status()
for file in resp.json()["data"]["files"]:
raw = base64.b64decode(file["data"])
Path(file["filename"]).write_bytes(raw)
print(f"Saved {file['filename']} ({len(raw):,} bytes)")
convert_to_webp(os.environ["SCENESKU_API_KEY"], ["product.png", "banner.jpg"], quality=85)
Full TypeScript and Python examples with sample images are on GitHub → scenesku/scenesku-webp-converter-api . A no-code browser tool is also available at /tools/convert.