Viewrium Docs
Guides

Upload a finished model

Bring your own 3D file with model_url - Viewrium converts it to GLB and hosts the viewer.

If you already have a 3D model, you do not need to generate one. Pass a model_url and Viewrium converts it to GLB, stores it, and gives you the same hosted 3D/AR viewer, embed, and analytics as a generated model. The analysis and the pipeline are skipped entirely - this is a fast, store-only path.

Supported formats

model_url must point at a hosted 3D file in one of these formats:

glb, gltf, obj, stl, ply, dae

A .glb is validated and stored as-is; the other formats are converted to GLB for you.

Request

Python
from viewrium import ModelDimensions, ProductCreateRequest, ProductDraft, Viewrium

client = Viewrium("sk_live_...")

product = client.products.create(
    ProductCreateRequest(
        model_url="https://cdn.example.com/models/oak-chair.glb",
        draft=ProductDraft(
            title="Oak dining chair",
            dimensions=ModelDimensions(height=92, width=45, depth=52),  # cm
        ),
    )
)
# `model_url` never parks, so this is a Product.
print(product.id, product.display_status)
TypeScript
import { Viewrium } from "@viewrium/sdk";

const client = new Viewrium({ apiKey: "sk_live_..." });

const product = await client.products.create({
  model_url: "https://cdn.example.com/models/oak-chair.glb",
  draft: {
    title: "Oak dining chair",
    dimensions: { height: 92, width: 45, depth: 52 }, // cm
  },
});

Notes

  • It never parks. A finished GLB has nothing to analyze and nothing to price, so create commits immediately and returns the product (HTTP 202) while conversion and storage run. There is no resume_token on this path and overrides do not apply.
  • No catalog images. model_url orders the model half only - the product has a model and no image positions. Order images for it afterward with products.order.
  • Set dimensions (any one to three axes, cm by default - send unit for anything else) so the model displays at true size in AR. You can also re-scale later with products.rescale.
  • The file must be publicly reachable so Viewrium can fetch it.

Then

Wait for display_status to leave generating by polling or webhooks; product.model.glb_url then points at the stored, converted GLB (not your original URL). Publish the product and embed it with the <viewrium-model> component.

Ordering the missing half

products.order asks for what the product does not have yet - images onto a model-only product, or a model onto an images one. Like a create, it parks: the additions come back priced, inside a token that products.create commits.

Python
from viewrium import ProductOrder, ProductOrderRequest

parked = client.products.order(product.id, ProductOrderRequest(order=ProductOrder(images=True)))
print(parked.cost.total_credits)
client.products.create(ProductCreateRequest(resume_token=parked.resume_token))
TypeScript
const parked = await client.products.order(product.id, { order: { images: true } });
await client.products.create({ resume_token: parked.resume_token });

Re-scaling an existing model

Already have a stored model and just need to fix its real-world size? Use products.rescale - it rewrites the stored GLB in place (the URL stays the same) and returns the product with the dimensions it actually achieved.

Python
from viewrium import DimensionUnit, ProductRescaleRequest

client.products.rescale(product.id, ProductRescaleRequest(height=92))
# or in another unit - stored dims stay cm either way
client.products.rescale(product.id, ProductRescaleRequest(height=36, unit=DimensionUnit.IN))
TypeScript
await client.products.rescale(product.id, { height: 92 });
await client.products.rescale(product.id, { height: 36, unit: "in" });

Uploaded files are the one case where Viewrium cannot tell which way the model faces - there are no product photos to read it from. If you set both width and depth and they come out swapped, say which horizontal axis the width belongs to with width_axis:

Python
from viewrium import ProductRescaleRequest, WidthAxis

client.products.rescale(
    product.id, ProductRescaleRequest(width=160, depth=90, width_axis=WidthAxis.X)
)
TypeScript
await client.products.rescale(product.id, { width: 160, depth: 90, width_axis: "x" });

On this page