Generate from images
Turn one or more product photos into catalog images and a GLB model with image_urls.
Pass a list of image URLs to products.create. Viewrium reads the product, plans the catalog
positions it can produce, prices the work, and parks. Commit the quote and it cuts the images out
and reconstructs the 3D model.
Ask for the quote
from viewrium import ModelDimensions, ProductCreateRequest, ProductDraft, ProductOrder, Viewrium
client = Viewrium("sk_live_...")
parked = client.products.create(
ProductCreateRequest(
image_urls=[
"https://cdn.example.com/lamp-front.jpg",
"https://cdn.example.com/lamp-side.jpg",
"https://cdn.example.com/lamp-back.jpg",
],
draft=ProductDraft(
title="Brass floor lamp",
dimensions=ModelDimensions(height=150), # cm, for AR real-size display
),
order=ProductOrder(images=True, model=True),
)
)
print(parked.cost.total_credits, [row.view for row in parked.plan])
print(parked.model.allowed, parked.model.unseen_views)import { Viewrium } from "@viewrium/sdk";
const client = new Viewrium({ apiKey: "sk_live_..." });
const parked = await client.products.create({
image_urls: [
"https://cdn.example.com/lamp-front.jpg",
"https://cdn.example.com/lamp-side.jpg",
"https://cdn.example.com/lamp-back.jpg",
],
draft: { title: "Brass floor lamp", dimensions: { height: 150 } }, // cm
order: { images: true, model: true },
});Commit it
from viewrium import ProductParked
product = client.products.create(ProductCreateRequest(resume_token=parked.resume_token))
assert not isinstance(product, ProductParked) # a resume always commits
print(product.id, product.display_status) # -> "<uuid>", "generating"if (parked.status !== "parked") throw new Error("unexpected: already committed");
const product = await client.products.create({ resume_token: parked.resume_token });Tips for good results
- Multiple angles help. Front, side, and back give the analysis more to work with than a single
hero shot - and they are what keeps viewpoints out of
model.unseen_views. - Clean, uncluttered images of a single product read best. Avoid busy backgrounds and multiple products in one frame.
- Use direct image URLs (
.jpg,.png,.webp) that are publicly reachable - not a gallery page. To work from a product page, usesource_urlinstead. - Give
dimensions(any one to three axes, cm by default - sendunitfor anything else) so the model shows at true size in AR. - Read the quote before you commit.
plannames every position and why;flags.reasonsare the analysis's own sentences about the product, meant to be shown as written.
If the model is refused
model.allowed: false with blocked_by: ["unseen_views"] means two or more of the viewpoints the
model needs would be invented - nothing in your photographs shows them. The honest fix is another
photograph. To take it anyway, quote again with overrides.force_model:
from viewrium import ProductOverrides
parked = client.products.create(
ProductCreateRequest(
image_urls=["https://cdn.example.com/lamp-front.jpg"],
draft=ProductDraft(title="Brass floor lamp"),
overrides=ProductOverrides(force_model=True),
)
)const parked = await client.products.create({
image_urls: ["https://cdn.example.com/lamp-front.jpg"],
draft: { title: "Brass floor lamp" },
overrides: { force_model: true },
});The override belongs to the request that is analyzed, so it goes on the quote, not on the resume. See the model verdict.
Then
The commit returns the product at display_status: "generating". Wait for it to settle by
polling or with webhooks, then read
product.model.glb_url and product.images.