API reference
The full /v1 REST surface, request conventions, and how each endpoint maps to the SDKs.
The Viewrium API is a single JSON REST API. This page covers the conventions that apply everywhere
and maps every /v1 endpoint to its SDK method. For request and response field definitions, the
typed Python and JavaScript SDKs are generated from
the same schema and are the most convenient reference.
Conventions
- Base URL -
https://api.viewrium.com. Every path below is relative to it. - Auth -
Authorization: Bearer <key>on every request. See Authentication. - JSON - request and response bodies are JSON. Timestamps are ISO 8601 in UTC.
- Pagination - list endpoints take
limitandoffsetquery params and returntotal,limit, andoffsetalongsidedata. - Scope - reads take
org_id(or default to your only organization) andscope=allfor every organization you reach. Writes always name one. - Repeated params - a filter that takes several values is repeated (
?tag=a&tag=b), andtag_match(all|any) says how the repeats combine. - Errors - every non-2xx response is the envelope
{ "error": { "code", "message", "details" } }.
Endpoints
Products
| Method | Path | SDK |
|---|---|---|
POST | /v1/products | products.create |
GET | /v1/products | products.list |
GET | /v1/products/{id} | products.retrieve |
PATCH | /v1/products/{id} | products.update |
DELETE | /v1/products/{id} | products.delete |
DELETE | /v1/products?ids=a&ids=b | products.batchDelete / batch_delete |
POST | /v1/products/publish | products.publish |
GET | /v1/products/tags | products.tags |
GET | /v1/products/export | products.export |
POST /v1/products is the single entrypoint - supply exactly one of image_urls, video_url,
source_url, model_url, image_paths, or resume_token. A fresh request answers 200 with a
parked quote (nothing written); a resume_token or a model_url answers 202 with the created
product. See How generation works.
GET /v1/products/{id} answers two shapes by principal: a session or sk_ key gets the product
with its assets, a pk_ key gets the allow-listed public projection - and only for a published
product with a ready model.
GET /v1/products/export streams a ZIP of baked files, selected by ids or by the list's own
filters, at most 200 products. image_review_status (default accepted) and include
(images, model) choose what goes in; the archive's manifest.json names every entry.
Assets and review
| Method | Path | SDK |
|---|---|---|
PATCH | /v1/products/{id}/images/{image_id} | products.updateImage / update_image |
PATCH | /v1/products/{id}/model | products.updateModel / update_model |
POST | /v1/products/{id}/model/rescale | products.rescale |
POST | /v1/products/{id}/order | products.order |
POST | /v1/products/{id}/review | products.review |
POST /v1/products/{id}/order orders the missing half - images onto a model-only product, or a
model onto an images one. It parks like a create: commit the returned token through
products.create. A 409 carries details.reason (no_analysis, generating,
images_ordered, model_exists, model_failed).
POST /v1/products/{id}/review is the batched flush: image decisions and settings, the model's
decision, and the product's user-set status, validated together and applied in order. A failed
bake is reported per image in bakes, never as a failed request.
Analytics
| Method | Path | SDK |
|---|---|---|
GET | /v1/usage | usage.get |
POST | /v1/beacon | beacon.send |
GET /v1/usage takes an arbitrary window (start / end, defaulting to the last 30 days),
granularity (hour | day), an event_type filter, and a scope: one organization (org_id),
every one you reach (scope=all), or one product (product_id, which needs no org_id).
Organization-internal traffic is excluded unless include_internal=true.
group_by=product additionally returns by_product: the window's best-performing products, ranked
by 3D views then AR entries, capped at 20, each with its title. The buckets themselves are
unchanged - to break one period down, ask again with the window narrowed to it. A subject with no
product row is a v1 scan: it still counts in totals, but it is never a by_product row.
POST /v1/beacon accepts a publishable (pk_) key and is what the embed uses to
report view / ar_enter / ar_session_ended events.
Webhooks
| Method | Path | SDK |
|---|---|---|
GET | /v1/webhooks | webhooks.list |
POST | /v1/webhooks | webhooks.create |
GET | /v1/webhooks/{id} | webhooks.retrieve |
PATCH | /v1/webhooks/{id} | webhooks.update |
DELETE | /v1/webhooks/{id} | webhooks.delete |
GET | /v1/webhooks/{id}/deliveries | webhooks.listDeliveries / list_deliveries |
See Webhooks for the event envelope and signature scheme.
Keys and projects
| Method | Path | SDK |
|---|---|---|
GET | /v1/api_keys | apiKeys.list / api_keys.list |
POST | /v1/api_keys | apiKeys.create / api_keys.create |
DELETE | /v1/api_keys/{id} | apiKeys.revoke / api_keys.revoke |
GET | /v1/projects | projects.list |
GET | /v1/projects/{id} | projects.retrieve |
Some management operations - creating API keys, for example - are restricted to account owners and admins and are typically done from the dashboard.
Health
| Method | Path | SDK |
|---|---|---|
GET | /v1/health | client.health() |
Key type access
Not every endpoint accepts every key type. In particular, publishable (pk_) keys are limited to
GET /v1/products/{id} and POST /v1/beacon, and are origin-gated. Everything else requires a
secret (sk_) key or a signed-in dashboard session. See
Authentication for the full model.
Not on the public API
Organization, team and billing management, comments, change requests, and the review app's own
tooling live on an internal surface that the dashboard uses and that is deliberately not part of
/v1. The Viewrium Shopify app, which will sync products from a store, is coming soon.