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 answers a ZIP of finished images - each one composited onto its
background with its shadow - selected by ids or by the list's own filters, at most 200
products. image_review_status (default accepted and pending) chooses which images go in;
the archive's manifest.json names every entry and every image skipped. The 3D model is never
included. When more images need finishing than one request can do, the answer is a 202 with
status: "queued": they are finished in the background, a download link is emailed to
notify_email, and the same request then streams the ZIP.
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. It
records decisions only; the finished images are made by the export.
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.